Merge Chromium + Blink git repositories

Blink SHA1: d32c4abb19d448507a840db6f41c4edf42678cc3
Blink revision: /blink/trunk@202666

BUG=431458

Cr-Commit-Position: refs/heads/master@{#350324}
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..f97f1bb
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,35 @@
+# Defines the Chromium style for automatic reformatting.
+# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
+BasedOnStyle: Chromium
+# This defaults to 'Auto'. Explicitly set it for a while, so that
+# 'vector<vector<int> >' in existing files gets formatted to
+# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
+# 'int>>' if the file already contains at least one such instance.)
+Standard: Cpp11
+# Make sure code like:
+# IPC_BEGIN_MESSAGE_MAP()
+#   IPC_MESSAGE_HANDLER(WidgetHostViewHost_Update, OnUpdate)
+# IPC_END_MESSAGE_MAP()
+# gets correctly indented.
+MacroBlockBegin: "^\
+BEGIN_MSG_MAP|\
+BEGIN_MSG_MAP_EX|\
+BEGIN_SAFE_MSG_MAP_EX|\
+CR_BEGIN_MSG_MAP_EX|\
+IPC_BEGIN_MESSAGE_MAP|\
+IPC_BEGIN_MESSAGE_MAP_WITH_PARAM|\
+IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN|\
+IPC_STRUCT_BEGIN|\
+IPC_STRUCT_BEGIN_WITH_PARENT|\
+IPC_STRUCT_TRAITS_BEGIN|\
+POLPARAMS_BEGIN|\
+PPAPI_BEGIN_MESSAGE_MAP$"
+MacroBlockEnd: "^\
+CR_END_MSG_MAP|\
+END_MSG_MAP|\
+IPC_END_MESSAGE_MAP|\
+IPC_PROTOBUF_MESSAGE_TRAITS_END|\
+IPC_STRUCT_END|\
+IPC_STRUCT_TRAITS_END|\
+POLPARAMS_END|\
+PPAPI_END_MESSAGE_MAP$"
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..21a13a6
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,7 @@
+## This page intentionally left blank. ##
+#
+# Workaround for VS2013 automatically creating .gitattributes files with
+# default settings that we don't want.
+# See also:
+# http://connect.microsoft.com/VisualStudio/feedback/details/804948/inappropriately-creates-gitattributes-file
+# http://crbug.com/342064
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b4526ca
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,446 @@
+*.gypcmd
+*.mk
+*.ncb
+*.opensdf
+*.orig
+*.props
+*.pyc
+*.rules
+*.sdf
+*.sln
+*.sublime-project
+*.sublime-workspace
+*.suo
+*.targets
+*.user
+*.vcproj
+*.vcxproj
+*.vcxproj.filters
+*.vpj
+*.vpw
+*.vpwhistu
+*.vtg
+*.xcodeproj
+*.xcworkspace
+*_proto.xml
+*_proto_cpp.xml
+*~
+!Android.mk
+.*.sw?
+.DS_Store
+.classpath
+.cproject
+.gdb_history
+.gdbinit
+.landmines
+.metadata
+.project
+.pydevproject
+.checkstyle
+cscope.*
+Session.vim
+tags
+Thumbs.db
+v8.log
+# Settings directories for eclipse
+/.externalToolBuilders/
+/.settings/
+/_out
+/android_emulator_sdk
+/ash/ash_unittests_run.xml
+/base/base_unittests_run.xml
+/breakpad/src/
+/build/Debug
+/build/Debug_x64
+/build/gomacc.lock
+/build/ipch/
+/build/Release
+/build/Release_x64
+/build/win_toolchain.json
+/build/util/LASTCHANGE*
+/build/util/support
+/build/x64/
+/build/linux/bin/eu-strip
+/build/linux/debian_*-sysroot/
+/buildtools
+# The Chrome OS build creates a /c symlink due to http://crbug.com/54866.
+/c
+/cdm
+/ceee/internal/
+/chrome/angle_unittests_run.xml
+/chrome/content_gl_tests_run.xml
+/chrome/gl_tests_run.xml
+/chrome/gles2_conform_test_run.xml
+/chrome/tab_capture_performance_tests_run.xml
+/chrome/telemetry_gpu_test_run.xml
+/chrome/app/theme/default_100_percent/google_chrome
+/chrome/app/theme/default_200_percent/google_chrome
+/chrome/app/theme/google_chrome
+/chrome/browser/autofill/internal
+/chrome/browser/chromeos/login/screenshot_testing/golden_screenshots/*.png
+/chrome/browser/chromeos/login/screenshot_testing/artifacts
+/chrome/browser/extensions/api/ledger/
+/chrome/browser/extensions/default_extensions/chromeos
+/chrome/browser/google/linkdoctor_internal
+/chrome/browser/internal
+/chrome/browser/performance_monitor/performance_monitor.xml
+/chrome/browser/protector/internal
+/chrome/browser/resources/chromeos/quickoffice
+/chrome/browser/resources/pdf/html_office
+/chrome/browser/resources/settings_internal/
+/chrome/browser/resources/software_rendering_list
+/chrome/browser/spellchecker/internal
+/chrome/browser_tests_run.xml
+/chrome/chrome_run.xml
+/chrome/chrome_user32_delay_imports.xml
+/chrome/chrome_version_resources.xml
+/chrome/common/extensions/api/api.xml
+/chrome/common/extensions/api/ledger/
+/chrome/Hammer
+/chrome/installer/linux/internal
+/chrome/installer/mac/internal
+/chrome/installer/mac/third_party/xz/xz
+/chrome/installer/mini_installer.xml
+/chrome/installer/mini_installer/mini_installer.aps
+/chrome/installer/mini_installer/support
+/chrome/installer/mini_installer_syzygy.xml
+/chrome/installer/mini_installer_tests_run.xml
+/chrome/installer_util_strings.xml
+/chrome/interactive_ui_tests_run.xml
+/chrome/setup.xml
+/chrome/setup_unittests.xml
+/chrome/supplement.gypi
+/chrome/sync_integration_tests_run.xml
+/chrome/test/chromeos/autotest/files/client/deps/chrome_test/test_src/
+/chrome/test/chromeos/autotest/files/client/deps/page_cycler_dep/test_src/
+/chrome/test/chromeos/autotest/files/client/deps/perf_data_dep/test_src/
+/chrome/test/chromeos/autotest/files/client/deps/pyauto_dep/test_src/
+/chrome/test/chromeos/autotest/files/client/deps/telemetry_dep/test_src/
+/chrome/test/data/extensions/api_test/permissions/nacl_enabled/bin
+/chrome/test/data/firefox2_profile/searchplugins
+/chrome/test/data/firefox2_searchplugins
+/chrome/test/data/firefox3_profile/searchplugins
+/chrome/test/data/firefox3_searchplugins
+/chrome/test/data/gpu/vectortown_endurance/
+/chrome/test/data/gpu/vt/
+/chrome/test/data/layout_tests
+/chrome/test/data/osdd
+/chrome/test/data/pdf_private
+/chrome/test/data/perf/canvas_bench
+/chrome/test/data/perf/frame_rate/content
+/chrome/test/data/perf/frame_rate/private
+/chrome/test/data/perf/private/
+/chrome/test/data/perf/third_party/
+/chrome/test/data/plugin/
+/chrome/test/data/webrtc/resources
+/chrome/test/media_router/internal
+/chrome/tools/memory
+/chrome/tools/test/reference_build
+/chrome/unit_tests_run.xml
+/chrome/web_ui_mojo_bindings.xml
+/chrome_elf/chrome_elf_resources.xml
+/chromecast/internal
+/clank
+/cloud_print/cloud_print_version_resources.xml
+/components/chrome_settings_proto_generated_compile.xml
+/components/cloud_policy_proto_generated_compile.xml
+/components/gcm_driver.xml
+/components/leveldb_proto_test_support.xml
+/components/rappor.xml
+/components/search_engines/prepopulated_engines.xml
+/components/suggestions.xml
+/components/variations.xml
+/content/browser/service_worker/proto.xml
+/content/content_browsertests_run.xml
+/content/content_common_mojo_bindings.xml
+/content/content_unittests_run.xml
+/content/test/data/gpu/generated/
+/content/test/data/gpu/gpu_reference/
+/content/test/data/layout_tests/
+/content/test/data/plugin/
+/content/web_ui_test_mojo_bindings.xml
+/data
+/delegate_execute
+/device/serial/device_serial_mojo.xml
+/google_apis/gcm/gcm.xml
+/google_apis/internal
+/googleurl
+/gpu/gles2_conform_test
+/gyp-mac-tool
+/internal_gyp
+/ios/build/util/CANARY_VERSION
+/ios/third_party/gcdwebserver/src
+/llvm
+/media/cast/logging/cast_logging_proto_lib.xml
+/media/cdm/ppapi/api
+/media/media_asm.xml
+/media/media_mojo_bindings.xml
+/media/test/data/internal
+/media/yuv_convert_simd_x86.xml
+/metro_driver
+/mojo/hello_world_service.xml
+/mojo/mojo_application_bindings.xml
+/mojo/mojo_application_manager_unittests.xml
+/mojo/mojo_apps_js_bindings.xml
+/mojo/mojo_apps_js_unittests_run.xml
+/mojo/mojo_clipboard_bindings.xml
+/mojo/mojo_content_handler_bindings.xml
+/mojo/mojo_core_window_manager_bindings.xml
+/mojo/mojo_echo_service_bindings.xml
+/mojo/mojo_example_service_bindings.xml
+/mojo/mojo_external_service_bindings.xml
+/mojo/mojo_geometry_bindings.xml
+/mojo/mojo_gles2_bindings.xml
+/mojo/mojo_gpu_bindings.xml
+/mojo/mojo_input_events_bindings.xml
+/mojo/mojo_js_unittests_run.xml
+/mojo/mojo_keyboard_bindings.xml
+/mojo/mojo_launcher_bindings.xml
+/mojo/mojo_media_viewer_bindings.xml
+/mojo/mojo_native_viewport_bindings.xml
+/mojo/mojo_navigation_bindings.xml
+/mojo/mojo_network_bindings.xml
+/mojo/mojo_public_bindings_unittests.xml
+/mojo/mojo_public_test_interfaces.xml
+/mojo/mojo_public_unittests.xml
+/mojo/mojo_sample_service.xml
+/mojo/mojo_shell_bindings.xml
+/mojo/mojo_shell_lib.xml
+/mojo/mojo_spy.xml
+/mojo/mojo_surface_id_bindings.xml
+/mojo/mojo_surfaces_app_bindings.xml
+/mojo/mojo_surfaces_bindings.xml
+/mojo/mojo_test_service_bindings.xml
+/mojo/mojo_view_manager_bindings.xml
+/mojo/mojo_window_manager_bindings.xml
+/mojo/mojo_wm_flow_embeddee_bindings.xml
+/mojo/mojo_wm_flow_embedder_bindings.xml
+/mojo/mojom_test.xml
+/mojo/sample_service.xml
+/native_client
+/net/Debug
+/net/net_derived_sources.xml
+/net/net_unittests_run.xml
+/net/Release
+/net/testserver.log
+/out*
+/ppapi/native_client/nacl_irt.xml
+/ppapi/native_client/ppapi_lib.xml
+/remoting/appengine/
+/remoting/host/installer/linux/internal/
+/remoting/internal/
+/remoting/proto/chromotocol_proto_lib.xml
+/remoting/remoting_core_resources.xml
+/remoting/remoting_elevated_controller.xml
+/remoting/remoting_host.xml
+/remoting/remoting_host_event_logger.xml
+/remoting/remoting_host_installation.xml
+/remoting/remoting_host_messages.xml
+/remoting/remoting_infoplist_strings.xml
+/remoting/remoting_lib_idl.xml
+/remoting/remoting_lib_rc.xml
+/remoting/remoting_me2me_host.xml
+/remoting/remoting_native_messaging_manifests.xml
+/remoting/remoting_version_resources.xml
+/remoting/remoting_windows_resources.xml
+/remoting/test/internal/
+/remoting/tools/internal/
+/remoting/webapp/app_remoting/internal/
+/sandbox/linux/seccomp-legacy/
+/sdch/open-vcdiff
+/seccompsandbox
+/signing_keys
+/skia/tools/clusterfuzz-data/
+/sql/sql_unittests_run.xml
+/sync/sync.xml
+/sync_testserver.log
+/testing/gmock
+/testing/gtest
+/testserver.log
+/tools/luci-go/linux64/isolate
+/tools/luci-go/mac64/isolate
+/tools/luci-go/win64/isolate.exe
+/third_party/__START__
+/third_party/accessibility-developer-tools/
+/third_party/adobe/flash/binaries
+/third_party/adobe/flash/symbols
+/third_party/amd/
+/third_party/android_protobuf/src
+/third_party/android_tools/
+/third_party/android_tools_internal/
+/third_party/android_webview_glue/src
+/third_party/angle
+/third_party/angle_dx11
+/third_party/apache-mime4j
+/third_party/apache-win32/bin/*.exe
+/third_party/apache-win32/bin/*.dll
+/third_party/apache-win32/bin/iconv/*.so
+/third_party/apache-win32/modules/*.so
+/third_party/apache-win32/modules/*.dll
+/third_party/appurify-python/src
+/third_party/asan
+/third_party/bidichecker
+/third_party/bison
+/third_party/boringssl/src
+/third_party/cacheinvalidation/cacheinvalidation_unittests_run.xml
+/third_party/cardboard-java/src
+/third_party/catapult
+/third_party/chromeos_login_manager
+/third_party/chromeos_text_input
+/third_party/chromite
+/third_party/class-dump/src
+/third_party/cld_2/src
+/third_party/colorama/src
+/third_party/crashpad/crashpad
+/third_party/cros
+/third_party/cros_system_api
+/third_party/custom_tabs_client/src
+/third_party/cygwin
+/third_party/deqp/src
+/third_party/directxsdk
+/third_party/dom_distiller_js/dist
+/third_party/drmemory/drmemory-windows-sfx.exe
+/third_party/drmemory/unpacked
+/third_party/elfutils/src
+/third_party/errorprone/lib
+/third_party/eyesfree/src
+/third_party/ffmpeg
+/third_party/findbugs
+/third_party/flac
+/third_party/fontconfig/src
+/third_party/freetype-android/src
+/third_party/freetype2/src
+/third_party/gles2_conform
+/third_party/gnu_binutils/
+/third_party/google_appengine_cloudstorage
+/third_party/google_toolbox_for_mac/src
+/third_party/googlemac
+/third_party/gperf
+/third_party/httpcomponents-client
+/third_party/httpcomponents-core
+/third_party/hunspell_dictionaries
+/third_party/icu
+/third_party/jarjar
+/third_party/jsoncpp/source
+/third_party/jsr-305/src
+/third_party/junit/src
+/third_party/kasko
+/third_party/khronos_glcts
+/third_party/leveldatabase/src
+/third_party/leveldb
+/third_party/libaddressinput/src
+/third_party/libexif/sources
+/third_party/libjingle/source
+/third_party/libjpeg_turbo
+/third_party/liblouis/src
+/third_party/libphonenumber/libphonenumber.xml
+/third_party/libphonenumber/libphonenumber_without_metadata.xml
+/third_party/libphonenumber/src
+/third_party/libsrtp
+/third_party/libvpx
+/third_party/libvpx_new/source/libvpx
+/third_party/libwebm/source
+/third_party/libyuv
+/third_party/lighttpd
+/third_party/llvm
+/third_party/llvm-allocated-type
+/third_party/llvm-build
+/third_party/lss
+/third_party/mesa/src
+/third_party/mingw-w64
+/third_party/minigbm/src
+/third_party/mkl
+/third_party/mocha
+/third_party/mockito/src
+/third_party/mojo/src/mojo/public/tools/prebuilt/
+/third_party/nacl_sdk_binaries/
+/third_party/nss
+/third_party/omaha/src/omaha
+/third_party/openmax_dl/
+/third_party/opus/src
+/third_party/pdfsqueeze
+/third_party/pdfium
+/third_party/pefile
+/third_party/perl
+/third_party/platformsdk_win7
+/third_party/platformsdk_win8
+/third_party/ppapi
+/third_party/psyco_win32
+/third_party/pthreads-win32
+/third_party/py_trace_event/src
+/third_party/pyelftools
+/third_party/pyftpdlib/src
+/third_party/pylib
+/third_party/pymox/src
+/third_party/python_24
+/third_party/python_26
+/third_party/pywebsocket/src
+/third_party/pywebsocket/src
+/third_party/requests/src
+/third_party/robolectric/lib
+/third_party/safe_browsing/testing
+/third_party/scons-2.0.1
+/third_party/sfntly/cpp
+/third_party/skia
+/third_party/smhasher/src
+/third_party/snappy/src
+/third_party/swiftshader/include/
+/third_party/syzygy
+/third_party/syzygy/binaries
+/third_party/tsan/
+/third_party/ub-uiautomator/lib
+/third_party/usb_ids
+/third_party/usrsctp/usrsctplib
+/third_party/v8-i18n
+/third_party/valgrind
+/third_party/v4l2capture
+/third_party/webdriver/pylib
+/third_party/webdriver/python/selenium
+/third_party/webgl
+/third_party/webgl/src
+/third_party/webpagereplay/
+/third_party/webrtc
+/third_party/widevine/cdm/chromeos
+/third_party/widevine/cdm/linux
+/third_party/widevine/cdm/mac
+/third_party/widevine/cdm/win
+/third_party/widevine/test/license_server
+/third_party/win_toolchain/.timestamps
+/third_party/win_toolchain/files
+/third_party/wix
+/third_party/xdg-utils
+/third_party/xulrunner-sdk
+/third_party/yasm/binaries
+/third_party/yasm/generate_files.xml
+/third_party/yasm/source/patched-yasm
+/third_party/yasm/yasm.xml
+/tools/.bisect-builds-cache.json
+/tools/deps2git/
+/tools/distcc
+/tools/gn/bin/linux
+/tools/gn/bin/mac
+/tools/gn/bin/win
+/tools/grit
+/tools/gyp
+/tools/histograms
+/tools/json_schema_compiler/test/json_schema_compiler_tests.xml
+/tools/metrics/histograms/histograms.before.pretty-print.xml
+/tools/page_cycler/acid3
+/tools/perf/data
+/tools/perf/internal
+/tools/perf/results.html
+/tools/swarming_client
+/tools/tryserver
+/tools/win/link_limiter/build
+/ui/file_manager/internal
+/ui/keyboard/keyboard_mojom_bindings.xml
+/ui/surface/surface.xml
+/ui/surface/surface_gpu_tests.xml
+/v8
+# Results directory for run-webkit-tests. http://crbug.com/488288
+/webkit
+/webpagereplay_logs/
+/win8/delegate_execute/delegate_execute_version_resources.xml
+/win8/metro_driver/metro_driver_version_resources.xml
+/x86-generic_out/
+/xcodebuild
\ No newline at end of file
diff --git a/.gn b/.gn
new file mode 100644
index 0000000..a9552c7
--- /dev/null
+++ b/.gn
@@ -0,0 +1,220 @@
+# This file is used by the GN meta build system to find the root of the source
+# tree and to set startup options. For documentation on the values set in this
+# file, run "gn help dotfile" at the command line.
+
+# The location of the build configuration file.
+buildconfig = "//build/config/BUILDCONFIG.gn"
+
+# The secondary source root is a parallel directory tree where
+# GN build files are placed when they can not be placed directly
+# in the source tree, e.g. for third party source trees.
+secondary_source = "//build/secondary/"
+
+# These are the targets to check headers for by default. The files in targets
+# matching these patterns (see "gn help label_pattern" for format) will have
+# their includes checked for proper dependencies when you run either
+# "gn check" or "gn gen --check".
+check_targets = [
+  #"//apps/*",  # Medium-hard.
+  #"//ash/*",  # Medium-hard.
+  #"//base/*",  # Needs GN binary changes to work on Android.
+  "//blink/*",
+  "//breakpad/*",
+  "//build/*",
+  "//cc/*",
+
+  #"//chrome/*",  # Epic number of errors.
+  #"//chrome/installer/*", # A few errors, need to verify the size after fixing.
+  "//chromecast/*",
+
+  # TODO(brettw): Fix http://crbug.com/460828 and uncomment the following
+  # line.
+  #"//chrome_elf/*",
+  "//cloud_print/*",
+
+  #"//components/*",  # Lots of errors.
+  "//components/app_modal/*",
+  "//components/autofill/*",
+  "//components/bookmarks/*",
+  "//components/google/*",
+  "//components/history/*",
+
+  # TODO(dpranke): Reenable once v8 exports v8_base as a public_dep
+  #"//components/html_viewer/*",
+
+  "//components/mus/*",
+  "//components/omnibox/*",
+  "//components/os_crypt/*",
+  "//components/pref_registry/*",
+  "//components/undo/*",
+  "//components/update_client/*",
+  "//components/url_formatter/*",
+  "//components/url_matcher/*",
+  "//components/user_manager/*",
+  "//components/user_prefs/*",
+  "//components/variations/*",
+  "//components/wallpaper/*",
+  "//components/web_cache/*",
+  "//components/webcrypto/*",
+  "//components/web_modal/*",
+  "//components/web_view/*",
+  "//components/webdata/*",
+  "//components/webdata_services/*",
+
+  #"//content/*",  # A whole lot of errors.
+  "//courgette/*",
+  "//crypto/*",
+  "//data/*",
+  "//dbus/*",
+
+  #"//device/*",  # Ran into http://crbug.com/500761 adding dbus dependency
+
+  #"//extensions/*",  # Lots of errors.
+  #"//gin/*",  # Easy.
+  "//google_apis/*",
+  "//google_update/*",
+
+  #"//gpu/*",  # Lots of errors.
+  "//gpu:*",
+
+  #"//ios/*",
+  "//ipc/*",
+
+  #"//jingle/*",
+  "//mandoline/*",
+
+  #"//media/*",  # Lots of errors.
+  "mojo/*",
+
+  #"//native_client/*",
+  #"//net/*",  # Needs GN binary changes to work on Android.
+
+  #"//pdf/*",  # Medium-hard.
+  #"//ppapi/*",  # Lots of errors.
+  "//printing/*",
+
+  #"//remoting/*",  # Medium-hard.
+  #"//rlz/*",  # Needs checking on Windows.
+  #"//sandbox/*",  # Medium-hard.
+  "//sdch/*",
+  "//skia/*",
+  "//sql/*",
+  "//storage/*",
+  "//sync/*",
+  "//testing/*",
+
+  #"//third_party/*",  # May not ever want this.
+  "//tools/*",
+
+  #"//ui/*",  # Just a few problems.
+  "//url/*",
+  "//v8/*",
+]
+
+# These are the list of GN files that run exec_script. This whitelist exists
+# to force additional review for new uses of exec_script, which is strongly
+# discouraged except for gypi_to_gn calls.
+exec_script_whitelist = [
+  "//ash/BUILD.gn",
+  "//build/config/android/BUILD.gn",
+  "//build/config/android/config.gni",
+  "//build/config/android/internal_rules.gni",
+  "//build/config/android/rules.gni",
+  "//build/config/compiler/BUILD.gn",
+  "//build/config/gcc/gcc_version.gni",
+  "//build/config/ios/ios_sdk.gni",
+  "//build/config/linux/BUILD.gn",
+  "//build/config/linux/pkg_config.gni",
+  "//build/config/mac/mac_sdk.gni",
+  "//build/config/win/visual_studio_version.gni",
+  "//build/gn_helpers.py",
+  "//build/gypi_to_gn.py",
+  "//build/linux/BUILD.gn",
+  "//build/toolchain/gcc_toolchain.gni",
+  "//build/toolchain/mac/BUILD.gn",
+  "//build/toolchain/nacl/BUILD.gn",
+  "//build/toolchain/win/BUILD.gn",
+  "//build/util/version.gni",
+  "//chrome/android/BUILD.gn",
+  "//chrome/browser/BUILD.gn",
+  "//chrome/browser/chromeos/BUILD.gn",
+  "//chrome/browser/extensions/BUILD.gn",
+  "//chrome/browser/resources/chromeos/chromevox/BUILD.gn",
+  "//chrome/browser/media/router/BUILD.gn",
+  "//chrome/browser/ui/BUILD.gn",
+  "//chrome/chrome_tests.gni",
+  "//chrome/common/BUILD.gn",
+  "//chrome/common/extensions/api/schemas.gni",
+  "//chrome/renderer/BUILD.gn",
+  "//chrome/test/BUILD.gn",
+  "//chrome/utility/BUILD.gn",
+  "//chromeos/BUILD.gn",
+
+  # TODO(dgn): Layer violation but breaks the build otherwise, see
+  # https://crbug.com/474506
+  "//clank/java/BUILD.gn",
+  "//clank/native/BUILD.gn",
+
+  "//components/domain_reliability/BUILD.gn",
+  "//components/scheduler/scheduler.gni",
+  "//content/browser/browser.gni",
+  "//content/child/child.gni",
+  "//content/common/common.gni",
+  "//content/content.gni",
+  "//content/public/android/BUILD.gn",
+  "//content/renderer/renderer.gni",
+  "//content/test/BUILD.gn",
+  "//content/utility/utility.gni",
+  "//extensions/common/api/schemas.gni",
+  "//extensions/extensions.gni",
+  "//extensions/shell/app_shell.gni",
+  "//extensions/shell/common/api/schemas.gni",
+  "//google_apis/BUILD.gn",
+  "//gpu/gles2_conform_support/BUILD.gn",
+  "//jingle/BUILD.gn",
+  "//net/BUILD.gn",
+  "//ppapi/ppapi_sources.gni",
+  "//printing/BUILD.gn",
+  "//remoting/host/BUILD.gn",
+  "//remoting/remoting_srcs.gni",
+  "//remoting/remoting_version.gni",
+  "//skia/BUILD.gn",
+  "//third_party/android_platform/BUILD.gn",
+  "//third_party/angle/BUILD.gn",
+  "//third_party/angle/src/tests/BUILD.gn",
+  "//third_party/boringssl/BUILD.gn",
+  "//third_party/catapult/tracing/BUILD.gn",
+  "//third_party/cld_2/BUILD.gn",
+  "//third_party/cython/rules.gni",
+  "//third_party/google_input_tools/inputview.gni",
+  "//third_party/harfbuzz-ng/BUILD.gn",
+  "//third_party/libaddressinput/BUILD.gn",
+  "//third_party/opus/BUILD.gn",
+  "//third_party/WebKit/Source/bindings/bindings.gni",
+  "//third_party/WebKit/Source/bindings/scripts/scripts.gni",
+  "//third_party/WebKit/Source/config.gni",
+  "//third_party/WebKit/Source/core/core.gni",
+  "//third_party/WebKit/Source/devtools/BUILD.gn",
+  "//third_party/WebKit/Source/modules/modules.gni",
+  "//third_party/WebKit/Source/platform/BUILD.gn",
+  "//third_party/WebKit/Source/platform/platform.gni",
+  "//third_party/WebKit/Source/web/BUILD.gn",
+  "//third_party/WebKit/Source/wtf/BUILD.gn",
+  "//third_party/WebKit/public/BUILD.gn",
+  "//tools/gn/BUILD.gn",
+  "//tools/gn/build_settings.h",
+  "//tools/gn/command_help.cc",
+  "//tools/gn/docs/language.md",
+  "//tools/gn/format_test_data/053.gn",
+  "//tools/gn/format_test_data/053.golden",
+  "//tools/gn/format_test_data/055.gn",
+  "//tools/gn/format_test_data/055.golden",
+  "//tools/gn/function_exec_script.cc",
+  "//tools/gn/gn.gyp",
+  "//tools/gn/input_conversion.cc",
+  "//tools/gn/misc/emacs/gn.el",
+  "//tools/gn/misc/vim/syntax/gn.vim",
+  "//tools/gn/setup.cc",
+  "//ui/accessibility/BUILD.gn",
+  "//ui/views/BUILD.gn",
+]
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..7614acb
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,654 @@
+# Names should be added to this file with this pattern:
+#
+# For individuals:
+#   Name <email address>
+#
+# For organizations:
+#   Organization <fnmatch pattern>
+#
+# See python fnmatch module documentation for more information.
+
+Aaron Jacobs <samusaaron3@gmail.com>
+Aaron Leventhal <aaronlevbugs@gmail.com>
+Aaron Randolph <aaron.randolph@gmail.com>
+Abhijeet Kandalkar <abhijeet.k@samsung.com>
+Abhishek Agarwal <abhishek.a21@samsung.com>
+Abhishek Singh <abhi.rathore@samsung.com>
+Adam Roben <adam@github.com>
+Adam Treat <adam.treat@samsung.com>
+Addanki Gandhi Kishor <kishor.ag@samsung.com>
+Adenilson Cavalcanti <a.cavalcanti@samsung.com>
+Aditya Bhargava <heuristicist@gmail.com>
+Abhishek Kanike <abhishek.ka@samsung.com>
+Ajay Berwal <ajay.berwal@samsung.com>
+Ajay Berwal <a.berwal@samsung.com>
+Ajith Kumar V <ajith.v@samsung.com>
+Aku Kotkavuo <a.kotkavuo@partner.samsung.com>
+Alex Gabriel <minilogo@gmail.com>
+Alex Gartrell <agartrell@cmu.edu>
+Alex Henrie <alexhenrie24@gmail.com>
+Alex Scheele <alexscheele@gmail.com>
+Alexander Sulfrian <alexander@sulfrian.net>
+Alexandre Abreu <wiss1976@gmail.com>
+Alexandru Chiculita <achicu@adobe.com>
+Alexey Korepanov <alexkorep@gmail.com>
+Alexis Menard <alexis.menard@intel.com>
+Alfredo Hernandez <ahernandez.miralles@gmail.com>
+Ali Vathi <ali.akbar@gmail.com>
+Ambarish Rapte <ambarish.r@samsung.com>
+Amit Sarkar <amit.srkr@samsung.com>
+Amogh Bihani <amogh.bihani@samsung.com>
+Amruth Raj <amruthraj@motorola.com>
+Amruth Raj <ckqr36@motorola.com>
+Anand Ratn <anand.ratn@samsung.com>
+Anastasios Cassiotis <tom.cassiotis@gmail.com>
+Ancil George <ancilgeorge@samsung.com>
+Andrei Parvu <andrei.prv@gmail.com>
+Andrei Parvu <parvu@adobe.com>
+Andrew Brampton <me@bramp.net>
+Andrew Tulloch <andrew@tullo.ch>
+Anish Patankar <anish.p@samsung.com>
+Ankit Kumar <ankit2.kumar@samsung.com>
+Ankur Verma <ankur1.verma@samsung.com>
+Anne Kao <annekao94@gmail.com>
+Anssi Hannula <anssi.hannula@iki.fi>
+Antonio Gomes <a1.gomes@sisa.samsung.com>
+Anuj Kumar Sharma <anujk.sharma@samsung.com>
+Arnaud Renevier <a.renevier@samsung.com>
+Arpita Bahuguna <a.bah@samsung.com>
+Arthur Lussos <developer0420@gmail.com>
+Arun Kulkarni <kulkarni.a@samsung.com>
+Arun Kumar <arun87.kumar@samsung.com>
+Arun Mankuzhi <arun.m@samsung.com>
+Arunoday Sarkar <a.sarkar.arun@gmail.com>
+Arunprasad Rajkumar <ararunprasad@gmail.com>
+Arunprasad Rajkumar <arurajku@cisco.com>
+Ashlin Joseph <ashlin.j@samsung.com>
+Attila Dusnoki <dati91@gmail.com>
+Avinaash Doreswamy <avi.nitk@samsung.com>
+Balazs Kelemen <b.kelemen@samsung.com>
+Baul Eun <baul.eun@samsung.com>
+Behara Mani Shyam Patro <behara.ms@samsung.com>
+Bem Jones-Bey <bemajaniman@gmail.com>
+Bem Jones-Bey <bjonesbe@adobe.com>
+Ben Fiola <benfiola@gmail.com>
+Ben Karel <eschew@gmail.com>
+Ben Noordhuis <ben@strongloop.com>
+Benjamin Dupont <bedupont@cisco.com>
+Benjamin Jemlich <pcgod99@gmail.com>
+Bernard Cafarelli <voyageur@gentoo.org>
+Bhanukrushana Rout <b.rout@samsung.com>
+Bobby Powers <bobbypowers@gmail.com>
+Branden Archer <bma4@zips.uakron.edu>
+Brendan Long <self@brendanlong.com>
+Brian G. Merrell <bgmerrell@gmail.com>
+Brian Konzman, SJ <b.g.konzman@gmail.com>
+Brian Luft <brian@electroly.com>
+Brian Merrell, Novell Inc. <bgmerrell@gmail.com>
+Bruno Calvignac <bruno@flock.com>
+Bruno de Oliveira Abinader <brunoabinader@gmail.com>
+Bryan Donlan <bdonlan@gmail.com>
+Byoungkwon Ko <gogag2@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>
+Changjun Yang <changjun.yang@intel.com>
+Changyeon Kim <cyzero.kim@samsung.com>
+Chansik Yun <chansik.yun@gmail.com>
+Chaobin Zhang <zhchbin@gmail.com>
+Chris Greene <cwgreene@amazon.com>
+Chris Harrelson <chrishtr@gmail.com>
+Chris Nardi <hichris123@gmail.com>
+Chris Tserng <tserng@amazon.com>
+Chris Vasselli <clindsay@gmail.com>
+Christophe Dumez <ch.dumez@samsung.com>
+Christopher Dale <chrelad@gmail.com>
+Clemens Fruhwirth <clemens@endorphin.org>
+Clement Scheelfeldt Skau <clementskau@gmail.com>
+Clinton Staley <clintstaley@chromium.org>
+Clinton Staley <clintstaley@gmail.com>
+Craig Schlenter <craig.schlenter@gmail.com>
+Daegyu Lee <na7jun8gi@gmail.com>
+Dai Chunyang <chunyang.dai@intel.com>
+Daiwei Li <daiweili@suitabletech.com>
+Dan McCombs <overridex@gmail.com>
+Daniel Bomar <dbdaniel42@gmail.com>
+Daniel Carvalho Liedke <dliedke@gmail.com>
+Daniel Imms <daniimms@amazon.com>
+Daniel Johnson <danielj41@gmail.com>
+Daniel Lockyer <thisisdaniellockyer@gmail.com>
+Daniel Nishi <dhnishi@gmail.com>
+Daniel Platz <daplatz@googlemail.com>
+Daniel Shaulov <dshaulov@ptc.com>
+Daniel Trebbien <dtrebbien@gmail.com>
+Darshini KN <kn.darshini@samsung.com>
+David Benjamin <davidben@mit.edu>
+David Erceg <erceg.david@gmail.com>
+David Fox <david@davidjfox.com>
+David Futcher <david.mike.futcher@gmail.com>
+David Leen <davileen@amazon.com>
+David McAllister <mcdavid@amazon.com>
+David Spellman <dspell@amazon.com>
+Debashish Samantaray <d.samantaray@samsung.com>
+Deepak Dilip Borade <deepak.db@samsung.com>
+Deepak Mittal <deepak.m1@samsung.com>
+Deepak Singla <deepak.s@samsung.com>
+Derek Halman <d.halman@gmail.com>
+Devlin Cronin <rdevlin.cronin@gmail.com>
+Diego Ferreiro Val <elfogris@gmail.com>
+Dillon Sellars <dill.sellars@gmail.com>
+Divya Bansal <divya.bansal@samsung.com>
+Dominic Jodoin <dominic.jodoin@gmail.com>
+Dominik Röttsches <dominik.rottsches@intel.com>
+Don Woodward <woodward@adobe.com>
+Dongjun Kim <djmix.kim@samsung.com>
+Dongseong Hwang <dongseong.hwang@intel.com>
+Dongwoo Joshua Im <dw.im@samsung.com>
+Douglas F. Turner <doug.turner@gmail.com>
+Dustin Doloff <doloffd@amazon.com>
+Ebrahim Byagowi <ebraminio@gmail.com>
+Eduardo Lima (Etrunko) <eblima@gmail.com>
+Eduardo Lima (Etrunko) <eduardo.lima@intel.com>
+Edward Baker <edward.baker@intel.com>
+Edward Crossman <tedoc2000@gmail.com>
+Eero Häkkinen <e.hakkinen@samsung.com>
+Egor Starkov <egor.starkov@samsung.com>
+Ehsan Akhgari <ehsan.akhgari@gmail.com>
+Elan Ruusamäe <elan.ruusamae@gmail.com>
+Eric Ahn <byungwook.ahn@gmail.com>
+Eric Rescorla <ekr@rtfm.com>
+Erik Hill <erikghill@gmail.com>
+Erik Sjölund <erik.sjolund@gmail.com>
+Eriq Augustine <eriq.augustine@gmail.com>
+Etienne Laurin <etienne@atnnn.com>
+Evan Peterson <evan.peterson.ep@gmail.com>
+Evan Wallace <evan.exe@gmail.com>
+Evangelos Foutras <evangelos@foutrelis.com>
+Evgeniy Dushistov <dushistov@gmail.com>
+Evgeny Agafonchikov <evgeny.agafonchikov@akvelon.com>
+Fabien Tassin <fta@sofaraway.org>
+Felix H. Dahlke <fhd@ubercode.de>
+Fernando Jiménez Moreno <ferjmoreno@gmail.com>
+Finbar Crago <finbar.crago@gmail.com>
+François Beaufort <beaufort.francois@gmail.com>
+Francois Kritzinger <francoisk777@gmail.com>
+Francois Rauch <leopardb@gmail.com>
+Frédéric Jacob <frederic.jacob.78@gmail.com>
+Frédéric Wang <fred.wang@free.fr>
+Gaetano Mendola <mendola@gmail.com>
+Gajendra N <gajendra.n@samsung.com>
+Gajendra Singh <wxjg68@motorola.com>
+Gao Chun <chun.gao@intel.com>
+Gao Chun <gaochun.dev@gmail.com>
+George Liaskos <geo.liaskos@gmail.com>
+Georgy Buranov <gburanov@gmail.com>
+Gitanshu Mehndiratta <g.mehndiratt@samsung.com>
+Giuseppe Iuculano <giuseppe@iuculano.it>
+Glenn Adams <glenn@chromium.org>
+Gnanasekar Somanathan <gnanasekar.s@samsung.com>
+Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
+Goutham Jagannatha <wrm364@motorola.com>
+Graham Yoakum <gyoakum@skobalt.com>
+Gregory Davis <gpdavis.chromium@gmail.com>
+Grzegorz Czajkowski <g.czajkowski@samsung.com>
+Guangzhen Li <guangzhen.li@intel.com>
+Gurpreet Kaur <k.gurpreet@samsung.com>
+Gustav Tiger <gustav.tiger@sonymobile.com>
+Gyuyoung Kim <gyuyoung.kim@navercorp.com>
+Gzob Qq <gzobqq@gmail.com>
+Habib Virji <habib.virji@samsung.com>
+Haitao Feng <haitao.feng@intel.com>
+Halley Zhao <halley.zhao@intel.com>
+Halton Huo <halton.huo@intel.com>
+Haojian Wu <hokein.wu@gmail.com>
+Hari Singh <hari.singh1@samsung.com>
+Harpreet Singh Khurana <harpreet.sk@samsung.com>
+Harshikesh Kumar <harshikeshnobug@gmail.com>
+Hautio Kari <khautio@gmail.com>
+Heejin R. Chung <heejin.r.chung@samsung.com>
+Heeyoun Lee <heeyoun.lee@samsung.com>
+Himanshu Joshi <h.joshi@samsung.com>
+Holger Kraus <kraush@amazon.com>
+Hong Zheng <hong.zheng@intel.com>
+Hongbo Min <hongbo.min@intel.com>
+Horia Olaru <horia.olaru@gmail.com>
+Horia Olaru <olaru@adobe.com>
+Hosung You <hosung.you@samsung.com>
+Huayong Xu <huayong.xu@samsung.com>
+Hugo Holgersson <hugo.holgersson@sonymobile.com>
+Hwanseung Lee <rucifer1217@gmail.com>
+Hyunjune Kim <hyunjune.kim@samsung.com>
+Hyunki Baik <hyunki.baik@samsung.com>
+Hyungwook Lee <withlhw@gmail.com>
+Hyungwook Lee <hyungwook.lee@navercorp.com>
+Ian Cullinan <cullinan@amazon.com>
+Ian Scott <ian.scott@arteris.com>
+Ibrar Ahmed <ibrar.ahmad@gmail.com>
+Ilia K <ki.stfu@gmail.com>
+Ion Rosca <rosca@adobe.com>
+Ivan Sham <ivansham@amazon.com>
+J. Ryan Stinnett <jryans@chromium.org>
+Jacob Mandelson <jacob@mandelson.org>
+Jaehun Lim <ljaehun.lim@samsung.com>
+Jaekyeom Kim <btapiz@gmail.com>
+Jaemin Seo <jaemin86.seo@samsung.com>
+Jaime Soriano Pastor <jsorianopastor@gmail.com>
+Jake Helfert <jake@helfert.us>
+Jakob Weigert <jakob.j.w@googlemail.com>
+Jakub Machacek <xtreit@gmail.com>
+James Choi <jchoi42@pha.jhu.edu>
+James Vega <vega.james@gmail.com>
+James Wei <james.wei@intel.com>
+James Willcox <jwillcox@litl.com>
+Jan Sauer <jan@jansauer.de>
+Janwar Dinata <j.dinata@gmail.com>
+Jared Shumway <jaredshumway94@gmail.com>
+Jared Sohn <jared.sohn@gmail.com>
+Jared Wein <weinjared@gmail.com>
+Jari Karppanen <jkarp@amazon.com>
+Jay Oster <jay@kodewerx.org>
+Jay Soffian <jaysoffian@gmail.com>
+Jeado Ko <haibane84@gmail.com>
+Jeongeun Kim <je_julie.kim@samsung.com>
+Jeremy Spiegel <jeremysspiegel@gmail.com>
+Jesse Miller <jesse@jmiller.biz>
+Jesus Sanchez-Palencia <jesus.sanchez-palencia.fernandez.fil@intel.com>
+Jiajia Qin <jiajia.qin@intel.com>
+Jie Chen <jie.a.chen@intel.com>
+Jihun Brent Kim <devgrapher@gmail.com>
+Jin Yang <jin.a.yang@intel.com>
+Jincheol Jo <jincheol.jo@navercorp.com>
+Jingwei Liu <kingweiliu@gmail.com>
+Jingyi Wei <wjywbs@gmail.com>
+Jinho Bang <jinho.bang@samsung.com>
+Jinkyu Seong <jinkyu.seong@lge.com>
+Jinwoo Song <jinwoo7.song@samsung.com>
+Jitendra Kumar Sahoo <jitendra.ks@samsung.com>
+Joachim Bauch <mail@joachim-bauch.de>
+Joachim Bauch <jbauch@webrtc.org>
+Joe Knoll <joe.knoll@workday.com>
+Joe Thomas <mhx348@motorola.com>
+Joel Stanley <joel@jms.id.au>
+Johannes Rudolph <johannes.rudolph@googlemail.com>
+John Yani <vanuan@gmail.com>
+John Yoo <nearbyh13@gmail.com>
+Johnson Lin <johnson.lin@intel.com>
+Jonathan Frazer <listedegarde@gmail.com>
+Jonathan Garbee <jonathan@garbee.me>
+Jonathan Hacker <jhacker@arcanefour.com>
+Jongsoo Lee <leejongsoo@gmail.com>
+Joone Hur <joone.hur@intel.com>
+Jorge Villatoro <jorge@tomatocannon.com>
+Joseph Gentle <josephg@gmail.com>
+Josh Triplett <josh@joshtriplett.org>
+Josh Triplett <josh.triplett@intel.com>
+Joshua Lock <joshua.lock@intel.com>
+Joshua Roesslein <jroesslein@gmail.com>
+Josué Ratelle <jorat1346@gmail.com>
+Juhui Lee <juhui24.lee@samsung.com>
+Julien Racle <jracle@logitech.com>
+Jun Jiang <jun.a.jiang@intel.com>
+Junchao Han <junchao.han@intel.com>
+JungJik Lee <jungjik.lee@samsung.com>
+Jungkee Song <jungkee.song@samsung.com>
+Junmin Zhu <junmin.zhu@intel.com>
+Kal Conley <kcconley@gmail.com>
+Kalyan Kondapally <kalyan.kondapally@intel.com>
+Kamil Jiwa <kamil.jiwa@gmail.com>
+Kangil Han <kangil.han@samsung.com>
+Kangyuan Shu <kangyuan.shu@intel.com>
+Kartikey Bhatt <kartikey@amazon.com>
+Kaspar Brand <googlecontrib@velox.ch>
+Kaustubh Atrawalkar <kaustubh.ra@gmail.com>
+Kaustubh Atrawalkar <kaustubh.a@samsung.com>
+Keene Pan <keenepan@linpus.com>
+Keith Chen <keitchen@amazon.com>
+Kenneth Rohde Christiansen <kenneth.r.christiansen@intel.com>
+Kenneth Zhou <knthzh@gmail.com>
+Keonho Kim <keonho07.kim@samsung.com>
+Ketan Goyal <ketan.goyal@samsung.com>
+Kevin Lee Helpingstine <sig11@reprehensible.net>
+Kevin M. McCormick <mckev@amazon.com>
+Kihong Kwon <kihong.kwon@samsung.com>
+Kim Christensen <kimworking@gmail.com>
+Kingshuk Jana <kingshuk.j@samsung.com>
+Kirk Shoop <kirk.shoop@microsoft.com>
+Klemen Forstnerič <klemen.forstneric@gmail.com>
+Krishna Chaitanya <krish.botta@samsung.com>
+Kristof Kosztyo <kkosztyo.u-szeged@partner.samsung.com>
+Krzysztof Czech <k.czech@samsung.com>
+Krzysztof Wolanski <k.wolanski@samsung.com>
+Kunal Thakar <kunalt@gmail.com>
+Kushal Pisavadia <kushi.p@gmail.com>
+Kwangho Shin <k_h.shin@samsung.com>
+Kyle Nahrgang <kpn24@drexel.edu>
+Kyungtae Kim <ktf.kim@samsung.com>
+Kyung Yeol Kim <chitacan@gmail.com>
+Laszlo Gombos <l.gombos@samsung.com>
+Laszlo Radanyi <bekkra@gmail.com>
+Lauren Yeun Kim <lauren.yeun.kim@gmail.com>
+Lauri Oherd <lauri.oherd@gmail.com>
+Legend Lee <guanxian.li@intel.com>
+Leith Bade <leith@leithalweapon.geek.nz>
+Leo Wolf <jclw@ymail.com>
+Leon Han <leon.han@intel.com>
+Leung Wing Chung <lwchkg@gmail.com>
+Li Yin <li.yin@intel.com>
+Lidwine Genevet <lgenevet@cisco.com>
+Lionel Landwerlin <lionel.g.landwerlin@intel.com>
+Lorenzo Stoakes <lstoakes@gmail.com>
+Lu Guanqun <guanqun.lu@gmail.com>
+Lucie Brozkova <lucinka.brozkova@gmail.com>
+Luke Inman-Semerau <luke.semerau@gmail.com>
+Luke Zarko <lukezarko@gmail.com>
+Maarten Lankhorst <m.b.lankhorst@gmail.com>
+Magnus Danielsson <fuzzac@gmail.com>
+Mahesh Kulkarni <mahesh.kk@samsung.com>
+Malcolm Wang <malcolm.2.wang@gmail.com>
+Manish Chhajer <chhajer.m@samsung.com>
+Manuel Braun <thembrown@gmail.com>
+Mao Yujie <maojie0924@gmail.com>
+Mao Yujie <yujie.mao@intel.com>
+Marco Rodrigues <gothicx@gmail.com>
+Mario Sanchez Prada <mario.prada@samsung.com>
+Mark Hahnenberg <mhahnenb@andrew.cmu.edu>
+Mark Seaborn <mrs@mythic-beasts.com>
+Martijn Croonen <martijn@martijnc.be>
+Martin Bednorz <m.s.bednorz@gmail.com>
+Martina Kollarova <martina.kollarova@intel.com>
+Masahiro Yado <yado.masa@gmail.com>
+Matheus Bratfisch <matheusbrat@gmail.com>
+Mathias Bynens <mathias@qiwi.be>
+Mathieu Meisser <mmeisser@logitech.com>
+Matt Arpidone <mma.public@gmail.com>
+Matt Strum <mstrum@amazon.com>
+Matthew Demarest <demarem@amazon.com>
+Matthew Robertson <matthewrobertson03@gmail.com>
+Matthew Turk <matthewturk@gmail.com>
+Matthew Willis <appamatto@gmail.com>
+Matthias Reitinger <reimarvin@gmail.com>
+Max Perepelitsyn <pph34r@gmail.com>
+Max Vujovic <mvujovic@adobe.com>
+Mayur Kankanwadi <mayurk.vk@samsung.com>
+Michael Gilbert <floppymaster@gmail.com>
+Michael Lopez <lopes92290@gmail.com>
+Michael Morrison <codebythepound@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>
+Mihai Tica <mitica@adobe.com>
+Mike Tilburg <mtilburg@adobe.com>
+Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+Milton Chiang <milton.chiang@mediatek.com>
+Mingmin Xie <melvinxie@gmail.com>
+Minsoo Max Koo <msu.koo@samsung.com>
+Mirela Budaes <mbudaes@gmail.com>
+Mirela Budaes <mbudaes@adobe.com>
+Mitchell Rosen <mitchellwrosen@chromium.org>
+Miyoung Shin <myid.shin@samsung.com>
+Mohamed I. Hammad <ibraaaa@gmail.com>
+Mohamed Mansour <m0.interactive@gmail.com>
+Mohammed Wajahat Ali Siddiqui <wajahat.s@samsung.com>
+Mohan Reddy <mohan.reddy@samsung.com>
+Mrunal Kapade <mrunal.kapade@intel.com>
+Myles C. Maxfield <mymax@amazon.com>
+Nagarjuna Atluri <nagarjuna.a@samsung.com>
+Naiem Shaik <naiem.shaik@gmail.com>
+Naoki Takano <takano.naoki@gmail.com>
+Naveen Bobbili <naveenbobbili@motorola.com>
+Naveen Bobbili <qghc36@motorola.com>
+Naveen Kumar S G <naveensg@samsung.com>
+Nayan Kumar K <qtc746@motorola.com>
+Nedeljko Babic <nedeljko.babic@imgtec.com>
+Nikhil Bansal <n.bansal@samsung.com>
+Nikita Ofitserov <himikof@gmail.com>
+Ningxin Hu <ningxin.hu@intel.com>
+Nitish Mehrotra <nitish.m@samsung.com>
+Pan Deng <pan.deng@intel.com>
+Parag Radke <nrqv63@motorola.com>
+Paritosh Kumar <paritosh.in@samsung.com>
+Patrasciuc Sorin Cristian <cristian.patrasciuc@gmail.com>
+Patrick Kettner <patrickkettner@gmail.com>
+Patrick Riordan <patrickriordan177@gmail.com>
+Patrik Ackland <patrikackland@gmail.com>
+Paul Adolph <padolph@netflix.com>
+Paul Kehrer <paul.l.kehrer@gmail.com>
+Paul Lind <paul.lind@imgtec.com>
+Paul Nettleship <pnettleship@gmail.com>
+Paul Robinson <paulrobinson85@googlemail.com>
+Paul Roskell <blurrech@gmail.com>
+Paul Wicks <pwicks86@gmail.com>
+Pavan Kumar Emani <pavan.e@samsung.com>
+Pavel Ivanov <paivanof@gmail.com>
+Paweł Hajdan jr <phajdan.jr@gmail.com>
+Pawel Forysiuk <p.forysiuk@samsung.com>
+Peng Jiang <leiyi.jp@gmail.com>
+Petar Jovanovic <petarj@mips.com>
+Peter Beverloo <peter@chromium.org>
+Peter Bright <drpizza@quiscalusmexicanus.org>
+Peter Brophy <pbrophy@adobe.com>
+Peter Collingbourne <peter@pcc.me.uk>
+Peter Gal <pgal.u-szeged@partner.samsung.com>
+Peter Molnar <pmolnar.u-szeged@partner.samsung.com>
+Philippe Beauchamp <philippe.beauchamp@gmail.com>
+Philippe Beaudoin <philippe.beaudoin@gmail.com>
+Pierre-Antoine LaFayette <pierre.lafayette@gmail.com>
+Po-Chun Chang <pochang0403@gmail.com>
+Pramod Begur Srinath <pramod.bs@samsung.com>
+Pranay Kumar <pranay.kumar@samsung.com>
+Prashant Hiremath <prashhir@cisco.com>
+Prashant Nevase <prashant.n@samsung.com>
+Praveen Akkiraju <praveen.anp@samsung.com>
+Pritam Nikam <pritam.nikam@samsung.com>
+Puttaraju R <puttaraju.r@samsung.com>
+Qiankun Miao <qiankun.miao@intel.com>
+Qing Zhang <qing.zhang@intel.com>
+Qi Yang <qi1988.yang@samsung.com>
+Radu Stavila <stavila@adobe.com>
+Radu Velea <radu.velea@intel.com>
+Rafael Antognolli <rafael.antognolli@intel.com>
+Raghavendra Ghatage <r.ghatage@samsung.com>
+Rahul Gupta <rahul.g@samsung.com>
+Raman Tenneti <raman.tenneti@gmail.com>
+Ramkumar Gokarnesan <ramkumar.gokarnesan@gmail.com>
+Ramkumar Ramachandra <artagnon@gmail.com>
+Ramya Vadlamudi <ramya.v@samsung.com>
+Randy Posynick <randy.posynick@gmail.com>
+Raphael Kubo da Costa <raphael.kubo.da.costa@intel.com>
+Ravi Phaneendra Kasibhatla <r.kasibhatla@samsung.com>
+Ravi Phaneendra Kasibhatla <ravi.kasibhatla@motorola.com>
+Renata Hodovan <rhodovan.u-szeged@partner.samsung.com>
+Rene Bolldorf <rb@radix.io>
+Rene Ladan <r.c.ladan@gmail.com>
+Rijubrata Bhaumik <rijubrata.bhaumik@intel.com>
+Rob Buis <rob.buis@samsung.com>
+Rob Wu <rob@robwu.nl>
+Robert Bear Travis <bear.travis@gmail.com>
+Robert Bear Travis <betravis@adobe.com>
+Robert Bradford <robert.bradford@intel.com>
+Robert Goldberg <goldberg@adobe.com>
+Robert Hogan <robhogan@gmail.com>
+Robert Nagy <robert.nagy@gmail.com>
+Robert Sesek <rsesek@bluestatic.org>
+Roland Takacs <rtakacs.u-szeged@partner.samsung.com>
+Rosen Dash <nqk836@motorola.com>
+Rosen Dash <rosen.dash@gmail.com>
+ruben <chromium@hybridsource.org>
+Ruben Terrazas <rubentopo@gmail.com>
+Ruiyi Luo <luoruiyi2008@gmail.com>
+Ryan Ackley <ryanackley@gmail.com>
+Ryan Norton <rnorton10@gmail.com>
+Ryan Sleevi <ryan-chromium-dev@sleevi.com>
+Ryan Yoakum <ryoakum@skobalt.com>
+Ryuan Choi <ryuan.choi@samsung.com>
+Saikrishna Arcot <saiarcot895@gmail.com>
+Salvatore Iovene <salvatore.iovene@intel.com>
+Sam Larison <qufighter@gmail.com>
+Sam McDonald <sam@sammcd.com>
+Sanghyun Park <sh919.park@samsung.com>
+Sanghyup Lee <sh53.lee@samsung.com>
+Sanjoy Pal <ncj674@motorola.com>
+Sanjoy Pal <sanjoy.pal@samsung.com>
+Sanne Wouda <sanne.wouda@gmail.com>
+Santosh Mahto <samahto@cisco.com>
+Sarath Singapati <s.singapati@gmail.com>
+Sarath Singapati <s.singapati@samsung.com>
+Saravanan KR <sramajay@cisco.com>
+Sathish Kuppuswamy <sathish.kuppuswamy@intel.com>
+Satoshi Matsuzaki <satoshi.matsuzaki@gmail.com>
+Sayan Nayak <sayan.nayak@samsung.com>
+Scott Blomquist <sblom@microsoft.com>
+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>
+Sevan Janiyan <venture37@geeklan.co.uk>
+Shahriar Rostami <shahriar.rostami@gmail.com>
+ShankarGanesh K <blr.bmlab@gmail.com>
+Shanmuga Pandi M <shanmuga.m@samsung.com>
+Shail Singhal <shail.s@samsung.com>
+Shashi Kumar <sk.kumar@samsung.com>
+Sherry Mou <wenjinm@amazon.com>
+Shez Baig <sbaig1@bloomberg.net>
+Shiliu Wang <aofdwsl@gmail.com>
+Shiliu Wang <shiliu.wang@intel.com>
+Shilpa Shri <shilpa.shri@samsung.com>
+Shivakumar JM <shiva.jm@samsung.com>
+Shouqun Liu <liushouqun@xiaomi.com>
+Shouqun Liu <shouqun.liu@intel.com>
+Shreeram Kushwaha <shreeram.k@samsung.com>
+Shreyas Gopal <shreyas.g@samsung.com>
+Shreyas VA <v.a.shreyas@gmail.com>
+Siba Samal <siba.samal@samsung.com>
+Simon Arlott <simon.arlott@gmail.com>
+Siva Kumar Gunturi <siva.gunturi@samsung.com>
+Sohan Jyoti Ghosh <sohan.jyoti@samsung.com>
+Song YeWen <ffmpeg@gmail.com>
+Soren Dreijer <dreijerbit@gmail.com>
+Srirama Chandra Sekhar Mogali <srirama.m@samsung.com>
+Stephen Searles <stephen.searles@gmail.com>
+Steven Pennington <spenn@engr.uvic.ca>
+Subrahmanya Praveen Munukutla <sataya.m@samsung.com>
+Suchit Agrawal <a.suchit@samsung.com>
+Sudarsana Babu Nagineni <sudarsana.nagineni@intel.com>
+Sudarshan Parthasarathy <sudarshan.p@samsung.com>
+Sujith S S <sujiths.s@samsung.com>
+Sungguk Lim <limasdf@gmail.com>
+Sungmann Cho <sungmann.cho@gmail.com>
+Sungmann Cho <sungmann.cho@navercorp.com>
+Sunitha Srivatsa <srivats@amazon.com>
+Suyash Sengar <suyash.s@samsung.com>
+Sunil Ratnu <sunil.ratnu@samsung.com>
+Swati Jaiswal <swa.jaiswal@samsung.com>
+Sylvain Zimmer <sylvinus@gmail.com>
+Szymon Piechowicz <szymonpiechowicz@o2.pl>
+Takeshi Kurosawa <taken.spc@gmail.com>
+Tanay Chowdhury <tanay.c@samsung.com>
+Tapu Kumar Ghose <ghose.tapu@gmail.com>
+Taylor Price <trprice@gmail.com>
+Ted Kim <neot0000@gmail.com>
+Ted Vessenes <tedvessenes@gmail.com>
+Teodora Novkovic <teodora.petrovic@gmail.com>
+Thiago Farina <thiago.farina@gmail.com>
+Thiago Marcos P. Santos <thiago.santos@intel.com>
+Thomas Butter <tbutter@gmail.com>
+Thomas Conti <tomc@amazon.com>
+Tiago Vignatti <tiago.vignatti@intel.com>
+Tim Ansell <mithro@mithis.com>
+Timo Reimann <ttr314@googlemail.com>
+Torsten Kurbad <google@tk-webart.de>
+Trevor Perrin <unsafe@trevp.net>
+U. Artie Eoff <ullysses.a.eoff@intel.com>
+Umar Hansa <umar.hansa@gmail.com>
+Vaibhav Agrawal <vaibhav1.a@samsung.com>
+Vamshikrishna Yellenki <vamshi@motorola.com>
+Vani Hegde <vani.hegde@samsung.com>
+Vartul Katiyar <vartul.k@samsung.com>
+Vedran Šajatović <vedran.sajatovic@gmail.com>
+Vernon Tang <vt@foilhead.net>
+Viatcheslav Ostapenko <sl.ostapenko@samsung.com>
+Victor Costan <costan@gmail.com>
+Viet-Trung Luu <viettrungluu@gmail.com>
+Vinay Anantharaman <vinaya@adobe.com>
+Vipul Bhasin <vipul.bhasin@gmail.com>
+Visa Putkinen <v.putkinen@partner.samsung.com>
+Vivek Galatage <vivek.vg@samsung.com>
+Volker Sorge <volker.sorge@gmail.com>
+Wesley Lancel <wesleylancel@gmail.com>
+Will Hirsch <chromium@willhirsch.co.uk>
+William Xie <william.xie@intel.com>
+Xiang Long <xiang.long@intel.com>
+Xinchao He <hexinchao@gmail.com>
+Xing Zhang <xzhang@adobe.com>
+Xu Samuel <samuel.xu@intel.com>
+Xuefei Ren <xrenishere@gmail.com>
+Xun Sun <xun.sun@intel.com>
+Yael Aharon <yael.aharon@intel.com>
+Yair Yogev <progame@chromium.org>
+Yang Gu <yang.gu@intel.com>
+Yarin Kaul <yarin.kaul@gmail.com>
+Ye Liu <cbakgly@gmail.com>
+Yi Shen <yi.shen@samsung.com>
+Yi Sun <ratsunny@gmail.com>
+Yoav Weiss <yoav@yoav.ws>
+Yoav Zilberberg <yoav.zilberberg@gmail.com>
+Yong Shin <sy3620@gmail.com>
+Yongsheng Zhu <yongsheng.zhu@intel.com>
+Yoshinori Sano <yoshinori.sano@gmail.com>
+YoungKi Hong <simon.hong81@gmail.com>
+Youngsoo Choi <kenshin.choi@samsung.com>
+Youngsun Suh <zard17@gmail.com>
+Yumikiyo Osanai <yumios.art@gmail.com>
+Yunchao He <yunchao.he@intel.com>
+Yuri Gorobets <yuri.gorobets@gmail.com>
+Zeno Albisser <zeno.albisser@digia.com>
+Zhaoze Zhou <zhaoze.zhou@partner.samsung.com>
+Zheng Chuang <zhengchuangscu@gmail.com>
+Zhenyu Liang <zhenyu.liang@intel.com>
+Zhenyu Shan <zhenyu.shan@intel.com>
+Zhuoyu Qian <zhuoyu.qian@samsung.com>
+Ziran Sun <ziran.sun@samsung.com>
+Zoltan Herczeg <zherczeg.u-szeged@partner.samsung.com>
+Zsolt Borbely <zsborbely.u-szeged@partner.samsung.com>
+Yongha Lee <yongha78.lee@samsung.com>
+方觉 (Fang Jue) <fangjue23303@gmail.com>
+Yupei Wang <perryuwang@tencent.com>
+Peng Hu <penghu@tencent.com>
+WenSheng He <wensheng.he@samsung.com>
+Raghu Ram Nagaraj <r.nagaraj@samsung.com>
+Chanho Park <parkch98@gmail.com>
+Payal Pandey <payal.pandey@samsung.com>
+Kenneth Strickland <ken.strickland@gmail.com>
+Olli Raula (Old name Olli Syrjälä) <olli.raula@intel.com>
+Vishal Bhatnagar <vishal.b@samsung.com>
+Yunsik Jang <yunsik.jang@lge.com>
+Siddharth Bagai <b.siddharth@samsung.com>
+Andrei Borza <andrei.borza@gmail.com>
+
+BlackBerry Limited <*@blackberry.com>
+Code Aurora Forum <*@codeaurora.org>
+Comodo CA Limited
+Google Inc. <*@google.com>
+Hewlett-Packard Development Company, L.P. <*@hp.com>
+Igalia S.L. <*@igalia.com>
+NVIDIA Corporation <*@nvidia.com>
+Opera Software ASA <*@opera.com>
+TeamSpeak Systems GmbH <*@teamspeak.com>
+The Chromium Authors <*@chromium.org>
+The MathWorks, Inc. <binod.pant@mathworks.com>
+Torchmobile Inc.
+Venture 3 Systems LLC <*@venture3systems.com>
+Yandex LLC <*@yandex-team.ru>
+ARM Holdings <*@arm.com>
+Macadamian <*@macadamian.com>
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000..c367108
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,942 @@
+# 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.
+
+# This is the root build file for GN. GN will start processing by loading this
+# file, and recursively load all dependencies until all dependencies are either
+# resolved or known not to exist (which will cause the build to fail). So if
+# you add a new build file, there must be some path of dependencies from this
+# file to your new one or GN won't know about it.
+
+import("//build/config/crypto.gni")
+import("//build/config/features.gni")
+import("//build/config/ui.gni")
+import("//build/module_args/v8.gni")
+import("//media/media_options.gni")
+
+if (is_android) {
+  import("//build/config/android/config.gni")
+}
+
+declare_args() {
+  # A list of extra dependencies to add to the root target. This allows a
+  # checkout to add additional targets without explicitly changing any checked-
+  # in files.
+  root_extra_deps = []
+}
+
+# This file defines the following four main targets:
+#
+# "both_gn_and_gyp" should list every root target (target that nothing else
+# depends on) built by GN that is also built in the GYP build.
+#
+# "gn_all" should (transitively) cause everything to be built; if you run
+# 'ninja gn_all' and then 'ninja all', the second build should do no work.
+#
+# "gn_only" should list every root target that is *not* intended to be built
+# in a GYP build. Because GN has different rules for deciding what an 'all'
+# build is, this may end up including targets that are actually defined in a
+# GYP build but not dependencies of GYP's "all" (and so not actually built).
+#
+# "gn_visibility": targets that are normally not visible to top-level targets,
+# but are built anyway by "all". Since we don't want any such targets, we
+# have this placeholder to make sure hidden targets that aren't otherwise
+# depended on yet are accounted for.
+#
+# TODO(GYP): crbug.com/481694. Make sure that the above is true and there are
+# scripts run on the bots that enforce this. Once the GYP migration is over,
+# we can collapse all of these targets as desired.
+
+group("gn_all") {
+  testonly = true
+
+  deps = [
+    ":both_gn_and_gyp",
+    ":gn_only",
+    ":gn_visibility",
+  ]
+}
+
+# The "both_gn_and_gyp" target should reflect every target that is built
+# in both the GN and GYP builds, and ideally it should match the
+# "both_gn_and_gyp" target in build/gn_migration.gypi line-for-line.
+#
+# TODO(GYP): Add build steps that check and enforce this on the bots.
+group("both_gn_and_gyp") {
+  testonly = true
+  deps = [
+    "//base:base_unittests",
+    "//chrome/installer",
+    "//components:components_unittests",
+    "//net:net_unittests",
+    "//skia:skia_unittests",
+    "//sql:sql_unittests",
+    "//sync:sync_unit_tests",
+    "//ui/base:ui_base_unittests",
+    "//ui/gfx:gfx_unittests",
+    "//url:url_unittests",
+  ]
+
+  if (!is_ios) {
+    # TODO(GYP): Figure out which of these should actually build on iOS,
+    # and whether there should be other targets that are iOS-only and missing.
+    deps += [
+      "//cc:cc_unittests",
+      "//chrome",
+      "//chrome/test:browser_tests",
+      "//chrome/test:interactive_ui_tests",
+      "//chrome/test:sync_integration_tests",
+      "//chrome/test:unit_tests",
+      "//chrome/test/chromedriver:chromedriver_unittests",
+      "//components:components_browsertests",
+      "//content/shell:content_shell",
+      "//content/test:content_browsertests",
+      "//content/test:content_perftests",
+      "//content/test:content_unittests",
+      "//crypto:crypto_unittests",
+      "//device:device_unittests",
+      "//extensions:extensions_browsertests",
+      "//extensions:extensions_unittests",
+      "//google_apis/gcm:gcm_unit_tests",
+      "//gpu:gpu_unittests",
+      "//gpu/gles2_conform_support:gles2_conform_test",
+      "//ipc:ipc_tests",
+      "//ipc/mojo:ipc_mojo_unittests",
+      "//jingle:jingle_unittests",
+      "//media:media_unittests",
+      "//media/cast:cast_unittests",
+      "//media/midi:midi_unittests",
+      "//mojo",
+      "//mojo/application/public/cpp",
+      "//mojo/common:mojo_common_unittests",
+      "//net:hpack_example_generator",
+      "//net:hpack_fuzz_mutator",
+      "//net:hpack_fuzz_wrapper",
+      "//net:net_perftests",
+      "//ppapi:ppapi_unittests",
+      "//ppapi/examples/2d",
+      "//ppapi/examples/audio",
+      "//ppapi/examples/audio_input",
+      "//ppapi/examples/compositor",
+      "//ppapi/examples/crxfs",
+      "//ppapi/examples/enumerate_devices",
+      "//ppapi/examples/file_chooser",
+      "//ppapi/examples/flash_topmost",
+      "//ppapi/examples/font",
+      "//ppapi/examples/gamepad",
+      "//ppapi/examples/gles2",
+      "//ppapi/examples/gles2_spinning_cube",
+      "//ppapi/examples/ime",
+      "//ppapi/examples/input",
+      "//ppapi/examples/media_stream_audio",
+      "//ppapi/examples/media_stream_video",
+      "//ppapi/examples/mouse_cursor",
+      "//ppapi/examples/mouse_lock",
+      "//ppapi/examples/printing",
+      "//ppapi/examples/scaling",
+      "//ppapi/examples/scripting",
+      "//ppapi/examples/stub",
+      "//ppapi/examples/threading",
+      "//ppapi/examples/url_loader",
+      "//ppapi/examples/video_capture",
+      "//ppapi/examples/video_decode",
+      "//ppapi/examples/video_effects",
+      "//ppapi/examples/video_encode",
+      "//printing:printing_unittests",
+      "//third_party/WebKit/Source/platform:heap_unittests",
+      "//third_party/WebKit/Source/platform:platform_unittests",
+      "//third_party/WebKit/Source/web:webkit_unit_tests",
+      "//third_party/WebKit/Source/wtf:wtf_unittests",
+      "//third_party/cacheinvalidation:cacheinvalidation_unittests",
+      "//third_party/codesighs",
+      "//third_party/mojo/src/mojo/edk/system:mojo_system_unittests",
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_bindings_unittests",
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_environment_unittests",
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_system_unittests",
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_utility_unittests",
+      "//third_party/pdfium/samples:pdfium_test",
+      "//third_party/smhasher:pmurhash",
+      "//tools/imagediff($host_toolchain)",
+      "//tools/gn",
+      "//tools/gn:gn_unittests",
+      "//tools/gn:generate_test_gn_data",
+      "//tools/telemetry:bitmaptools($host_toolchain)",
+      "//ui/accessibility:accessibility_unittests",
+      "//ui/app_list:app_list_unittests",
+      "//ui/display:display_unittests",
+      "//ui/events:events_unittests",
+      "//ui/gl:gl_unittests",
+      "//ui/touch_selection:ui_touch_selection_unittests",
+    ]
+  }
+
+  deps += root_extra_deps
+
+  if (enable_extensions && !is_mac) {
+    # TODO(GYP): Get this working on the mac?
+    deps += [ "//extensions/shell:app_shell_unittests" ]
+  }
+
+  if (enable_media_router) {
+    deps += [ "//chrome/browser/media/router" ]
+  }
+
+  if (enable_remoting) {
+    deps += [ "//remoting:remoting_all" ]
+  }
+
+  if (toolkit_views) {
+    deps += [ "//ui/views:views_unittests" ]
+  }
+
+  if (use_aura) {
+    deps += [ "//ui/wm:wm_unittests" ]
+  }
+
+  if (use_ozone) {
+    deps += [ "//ui/ozone" ]
+  }
+
+  if (use_x11) {
+    deps += [ "//tools/xdisplaycheck" ]
+  }
+
+  if (enable_configuration_policy) {
+    deps += [ "//components/policy:policy_templates" ]
+  }
+
+  if (v8_use_external_startup_data) {
+    deps += [ "//gin:gin_v8_snapshot_fingerprint" ]
+  }
+
+  if (is_win) {
+    deps += [ "//chrome/tools/build/win/syzygy:chrome_dll_syzygy" ]
+  }
+
+  if (is_android) {
+    deps += [
+      "//base/android/linker:chromium_android_linker",
+      "//build/android/gyp/test:hello_world",
+      "//build/android/rezip",
+      "//chrome/android:chrome_public_apk",
+      "//chrome/android:chrome_public_test_apk",
+      "//chrome/test/chromedriver/test/webview_shell:chromedriver_webview_shell_apk",
+      "//third_party/errorprone:chromium_errorprone",
+      "//tools/imagediff($host_toolchain)",
+
+      # TODO(GYP): Remove these when the components_unittests work.
+      "//components/history/core/test:test",
+      "//components/policy:policy_component_test_support",
+      "//components/policy:test_support",
+      "//components/rappor:test_support",
+      "//components/signin/core/browser:test_support",
+      "//components/sync_driver:test_support",
+      "//components/user_manager",
+      "//components/wallpaper",
+      "//content/shell/android:content_shell_apk",
+
+      # TODO(GYP): Are these needed, or will they be pulled in automatically?
+      "//third_party/android_tools:android_gcm_java",
+      "//third_party/android_tools:uiautomator_java",
+      "//third_party/android_tools:android_support_v13_java",
+      "//third_party/android_tools:android_support_v7_appcompat_java",
+      "//third_party/android_tools:android_support_v7_mediarouter_java",
+      "//third_party/mesa",
+      "//third_party/mockito:mockito_java",
+      "//third_party/openmax_dl/dl",
+      "//ui/android:ui_java",
+
+      # TODO(GYP): Are these needed?
+      "//chrome/test:test_support_unit",
+      "//third_party/smhasher:murmurhash3",
+      "//ui/message_center:test_support",
+    ]
+    deps -= [
+      "//chrome",  # TODO(GYP) ??
+      "//chrome/test:browser_tests",  # TODO(GYP) ??
+      "//chrome/test:interactive_ui_tests",  # TODO(GYP) ??
+      "//chrome/test:sync_integration_tests",  # TODO(GYP) ??
+      "//chrome/test:unit_tests",  # TODO(GYP)
+
+      # Chromedriver shouldn't be compiled on Android.
+      "//chrome/test/chromedriver:chromedriver_unittests",
+      "//extensions:extensions_browsertests",
+      "//extensions:extensions_unittests",
+      "//google_apis/gcm:gcm_unit_tests",
+      "//ipc:ipc_tests",  # TODO(GYP) ??
+      "//jingle:jingle_unittests",  # TODO(GYP) ??
+      "//net:hpack_example_generator",
+      "//net:hpack_fuzz_mutator",
+      "//net:hpack_fuzz_wrapper",
+      "//net:net_perftests",
+      "//ppapi/examples/2d",
+      "//ppapi/examples/audio",
+      "//ppapi/examples/audio_input",
+      "//ppapi/examples/compositor",
+      "//ppapi/examples/crxfs",
+      "//ppapi/examples/enumerate_devices",
+      "//ppapi/examples/file_chooser",
+      "//ppapi/examples/flash_topmost",
+      "//ppapi/examples/font",
+      "//ppapi/examples/gamepad",
+      "//ppapi/examples/gles2",
+      "//ppapi/examples/gles2_spinning_cube",
+      "//ppapi/examples/ime",
+      "//ppapi/examples/input",
+      "//ppapi/examples/media_stream_audio",
+      "//ppapi/examples/media_stream_video",
+      "//ppapi/examples/mouse_cursor",
+      "//ppapi/examples/mouse_lock",
+      "//ppapi/examples/printing",
+      "//ppapi/examples/scaling",
+      "//ppapi/examples/scripting",
+      "//ppapi/examples/stub",
+      "//ppapi/examples/threading",
+      "//ppapi/examples/url_loader",
+      "//ppapi/examples/video_capture",
+      "//ppapi/examples/video_decode",
+      "//ppapi/examples/video_effects",
+      "//ppapi/examples/video_encode",
+      "//third_party/pdfium/samples:pdfium_test",
+      "//tools/gn",
+      "//tools/gn:generate_test_gn_data",
+      "//tools/gn:gn_unittests",
+      "//ui/app_list:app_list_unittests",
+      "//url:url_unittests",
+    ]
+
+    if (has_chrome_android_internal) {
+      deps += [ "//clank" ]  # TODO(GYP) ??
+    }
+  }
+
+  if (is_linux) {  # TODO(GYP): || is_android || is_bsd?
+    deps += [
+      "//breakpad:core-2-minidump",
+      "//breakpad:minidump-2-core",
+    ]
+  }
+
+  if (is_chromeos) {
+    deps += [
+      "//chromeos:chromeos_unittests",
+      "//ui/chromeos:ui_chromeos_unittests",
+    ]
+  }
+
+  if (is_chromeos || is_mac || is_win) {
+    deps += [
+      "//rlz:rlz_id",
+      "//rlz:rlz_lib",
+      "//rlz:rlz_unittests",
+    ]
+  }
+
+  if (is_linux) {
+    # The following are definitely linux-only.
+    deps += [
+      "//breakpad:breakpad_unittests",
+      "//breakpad:generate_test_dump",
+      "//dbus:dbus_test_server",
+      "//dbus:dbus_unittests",
+      "//net:disk_cache_memory_test",
+      "//net:flip_in_mem_edsm_server",
+      "//net:flip_in_mem_edsm_server_unittests",
+      "//net:quic_client",
+      "//net:quic_server",
+      "//sandbox/linux:chrome_sandbox",
+      "//sandbox/linux:sandbox_linux_unittests",
+      "//sandbox/linux:sandbox_linux_jni_unittests",
+    ]
+
+    if (is_chromeos || use_ash) {
+      deps += [ "//components/session_manager/core" ]
+    }
+  }
+
+  if (is_ios || is_win || (is_linux && !is_chromeos)) {
+    deps += [
+      "//base:base_i18n_perftests",
+      "//base:base_perftests",
+      "//google_apis:google_apis_unittests",
+    ]
+  }
+
+  if (is_win || (is_linux && !is_chromeos)) {
+    # TODO(GYP): Figure out which of these should (and can) build
+    # for android/chromeos/mac/ios.
+    deps += [
+      "//base:check_example",
+      "//base:build_utf8_validator_tables",
+      "//cc:cc_perftests",
+      "//cc/blink:cc_blink_unittests",
+      "//chrome/test:load_library_perf_tests",
+      "//chrome/test:performance_browser_tests",
+      "//chrome/test:sync_performance_tests",
+      "//chrome/test/chromedriver:chromedriver",
+      "//chrome/test/chromedriver:chromedriver_tests",
+      "//chrome/tools/profile_reset:jtl_compiler",
+      "//components:components_perftests",
+      "//content/test:content_gl_tests",
+      "//content/test:content_gl_benchmark",
+      "//courgette:courgette",
+      "//courgette:courgette_fuzz",
+      "//courgette:courgette_minimal_tool",
+      "//courgette:courgette_unittests",
+      "//device:device_unittests",
+      "//gin:gin_shell",
+      "//gin:gin_unittests",
+      "//google_apis/gcm:mcs_probe",
+      "//gpu:gpu_perftests",
+      "//gpu:gl_tests",
+      "//ipc:ipc_perftests",
+      "//media:media_perftests",
+      "//media/cast:generate_barcode_video",
+      "//media/cast:generate_timecode_audio",
+      "//net:crash_cache",
+      "//net:crl_set_dump",
+      "//net:dns_fuzz_stub",
+      "//net:dump_cache",
+      "//net:gdig",
+      "//net:get_server_time",
+      "//net:net_watcher",  # TODO(GYP): This should be conditional on use_v8_in_net
+      "//net:run_testserver",
+      "//net:stress_cache",
+      "//net:tld_cleanup",
+      "//ppapi:pepper_hash_for_uma",
+      "//ppapi:ppapi_perftests",
+      "//sync:run_sync_testserver",
+      "//third_party/angle/src/tests:angle_end2end_tests",
+      "//third_party/angle/src/tests:angle_unittests",
+      "//third_party/codesighs:maptsvdifftool",
+      "//third_party/leveldatabase:env_chromium_unittests",
+      "//third_party/libaddressinput:libaddressinput_unittests",
+      "//third_party/libphonenumber:libphonenumber_unittests",
+      "//ui/compositor:compositor_unittests",
+    ]
+
+    if (enable_extensions) {
+      deps += [ "//extensions/shell:app_shell" ]
+    }
+
+    if (enable_nacl) {
+      deps += [ "//components/nacl:nacl_loader_unittests" ]
+    }
+
+    if (media_use_ffmpeg) {
+      deps += [ "//media:ffmpeg_regression_tests" ]
+    }
+
+    if (use_ash) {
+      deps += [
+        "//ash:ash_shell",
+        "//ash:ash_unittests",
+      ]
+    }
+
+    if (use_aura) {
+      deps += [
+        "//ui/aura:aura_unittests",
+        "//ui/aura:bench",
+        "//ui/aura:demo",
+      ]
+    }
+  }
+
+  if (is_linux && !is_chromeos) {
+    deps += [
+      # TODO(GYP): Figure out which of these should (and can) build
+      # under which other conditions.
+      "//build/sanitizers:copy_llvm_symbolizer",
+      "//chrome/test:chrome_app_unittests",
+      "//cloud_print:cloud_print_unittests",
+      "//components/network_hints/browser",
+      "//content/public/app:browser",
+      "//content/public/app:child",
+
+      # TODO(GYP): Remove this when the gles2 tests work
+      "//gpu/command_buffer/client:gles2_implementation_no_check",
+
+      "//gpu/khronos_glcts_support:khronos_glcts_test",  # TODO(GYP) crbug.com/471903 to make this complete.
+      "//media/cast:cast_benchmarks",
+      "//media/cast:tap_proxy",
+      "//mojo/application/public/cpp",
+      "//skia:filter_fuzz_stub",
+      "//skia:image_operations_bench",
+      "//sync/tools:sync_client",
+      "//sync/tools:sync_listen_notifications",
+      "//testing/gmock:gmock_main",
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_system_perftests",
+      "//tools/perf/clear_system_cache",
+      "//ui/keyboard:keyboard_unittests",
+      "//ui/message_center:message_center_unittests",
+      "//ui/snapshot:snapshot_unittests",
+      "//ui/views/examples:views_examples_with_content_exe",
+
+      "//third_party/codesighs:nm2tsv",
+      "//third_party/sqlite:sqlite_shell",
+    ]
+
+    if (current_toolchain == host_toolchain) {
+      # Do not build the breakpad utilities in cross-compiles.
+      deps += [
+        "//breakpad:dump_syms",
+        "//breakpad:microdump_stackwalk",
+        "//breakpad:minidump_dump",
+        "//breakpad:minidump_stackwalk",
+      ]
+    }
+
+    if (!is_debug && !is_component_build) {
+      deps += [ "//chrome/tools/service_discovery_sniffer" ]
+    }
+
+    if (toolkit_views) {
+      deps += [ "//ui/app_list:app_list_demo" ]
+    }
+
+    if (use_x11) {
+      if (target_cpu != "arm") {
+        deps += [ "//gpu/tools/compositor_model_bench" ]
+      }
+    }
+  }
+
+  if (is_mac) {
+    deps += [
+      "//breakpad:crash_inspector",
+      "//breakpad:dump_syms",
+      "//third_party/apple_sample_code",
+      "//third_party/molokocacao",
+    ]
+
+    # TODO(GYP): Remove these when the targets below work and these
+    # are pulled in automatically.
+    deps += [
+      "//cc/blink",
+      "//components/ui/zoom",
+      "//content",
+      "//content/test:test_support",
+      "//device/battery",
+      "//device/bluetooth",
+      "//device/nfc",
+      "//device/usb",
+      "//device/vibration",
+      "//media/blink",
+      "//pdf",
+      "//storage/browser",
+      "//third_party/brotli",
+      "//third_party/flac",
+      "//third_party/hunspell",
+      "//third_party/iccjpeg",
+      "//third_party/libphonenumber",
+      "//third_party/ots",
+      "//third_party/qcms",
+      "//third_party/smhasher:murmurhash3",
+      "//third_party/webrtc/system_wrappers",
+      "//ui/app_list:app_list_unittests",
+      "//ui/gfx:gfx_unittests",
+      "//ui/native_theme",
+      "//ui/snapshot",
+      "//ui/surface",
+    ]
+
+    # TODO(dpranke): These are as-yet untriaged but need at least the above.
+    deps -= [
+      "//chrome",  # TODO(GYP)
+      "//chrome/test:browser_tests",  # TODO(GYP)
+      "//chrome/test:interactive_ui_tests",  # TODO(GYP)
+      "//chrome/test:sync_integration_tests",  # TODO(GYP)
+      "//chrome/test:unit_tests",  # TODO(GYP)
+      "//components:components_browsertests",  # TODO(GYP)
+      "//components:components_unittests",  # TODO(GYP)
+      "//content/test:content_browsertests",  # TODO(GYP)
+      "//content/test:content_perftests",  # TODO(GYP)
+      "//device:device_unittests",  # TODO(GYP)
+      "//extensions:extensions_browsertests",  # TODO(GYP)
+      "//extensions:extensions_unittests",  # TODO(GYP)
+      "//mojo",  # TODO(GYP)
+      "//mojo/application/public/cpp",  # TODO(GYP)
+
+      # TODO(GYP): Re-enable this as soon as we can link Blink binaries on mac.
+      "//third_party/WebKit/Source/platform:heap_unittests",
+      "//third_party/WebKit/Source/platform:platform_unittests",
+      "//third_party/WebKit/Source/web:webkit_unit_tests",
+    ]
+  }
+
+  if (is_win) {
+    deps += [
+      "//base:pe_image_test",
+      "//chrome/installer/setup:setup_unittests",
+      "//chrome_elf:chrome_elf_unittests",
+      "//chrome_elf:dll_hash_main",
+      "//components/crash/content/tools:crash_service",
+      "//components/wifi:wifi_test",
+      "//net:quic_client",
+      "//net:quic_server",
+      "//sandbox/win:pocdll",
+      "//sandbox/win:sandbox_poc",
+      "//sandbox/win:sbox_integration_tests",
+      "//sandbox/win:sbox_unittests",
+      "//sandbox/win:sbox_validation_tests",
+      "//testing/gtest:gtest_main",
+      "//third_party/codesighs:msmap2tsv",
+      "//third_party/pdfium/samples:pdfium_diff",
+      "//ui/metro_viewer",
+    ]
+    deps -= [
+      "//crypto:crypto_unittests",  # TODO(GYP)
+      "//net:net_unittests",  # TODO(GYP)
+    ]
+  } else if (!is_android && !is_ios) {
+    deps += [ "//breakpad:symupload" ]
+  }
+
+  if (!is_ios) {
+    deps += [ "//gpu/skia_runner:skia_runner" ]
+  }
+}
+
+group("gn_only") {
+  testonly = true
+
+  deps = []
+
+  if (!is_ios) {
+    deps += [ "//mandoline:all" ]
+  }
+
+  if (!is_android && !is_ios) {
+    deps += [ "//components/proximity_auth:proximity_auth_unittests" ]
+  }
+
+  if (is_linux && !is_chromeos) {
+    # TODO(GYP): Figure out if any of these should be in gn_all
+    # and figure out how cross-platform they are
+    deps += [
+      ":gn_mojo_targets",
+      "//blimp",
+      "//chrome/browser/resources:extension_resource_demo",
+      "//chrome/installer/util:strings",
+      "//chrome:main_dll",
+      "//chrome/test:load_library_perf_tests",
+      "//chrome/tools/convert_dict",
+      "//components/constrained_window:unit_tests",
+      "//components/enhanced_bookmarks:test_support",
+      "//components/metrics:serialization",
+      "//components/password_manager/content/renderer:browser_tests",
+      "//components/rappor:unit_tests",
+      "//components/sessions:unit_tests",
+      "//media/blink:media_blink_unittests",
+      "//media/cast:udp_proxy",
+      "//native_client/src/trusted/debug_stub:gdb_rsp_unittest",
+      "//storage/browser:dump_file_system",
+      "//third_party/angle:libANGLE",
+      "//third_party/angle:libEGL",
+      "//third_party/angle:libGLESv2",
+      "//third_party/cld_2:cld_2_dynamic_data_tool",
+      "//third_party/leveldatabase:leveldb_arena_test",
+      "//third_party/leveldatabase:leveldb_bloom_test",
+      "//third_party/leveldatabase:leveldb_db_test",
+      "//third_party/leveldatabase:leveldb_crc32c_test",
+      "//third_party/leveldatabase:leveldb_cache_test",
+      "//third_party/leveldatabase:leveldb_env_test",
+      "//third_party/leveldatabase:leveldb_write_batch_test",
+      "//third_party/leveldatabase:leveldb_filter_block_test",
+      "//third_party/leveldatabase:leveldb_version_edit_test",
+      "//third_party/leveldatabase:leveldb_db_bench",
+      "//third_party/leveldatabase:leveldb_log_test",
+      "//third_party/leveldatabase:leveldb_corruption_test",
+      "//third_party/leveldatabase:leveldb_table_test",
+      "//third_party/leveldatabase:leveldb_skiplist_test",
+      "//third_party/leveldatabase:leveldb_filename_test",
+      "//third_party/leveldatabase:leveldb_dbformat_test",
+      "//third_party/pdfium/third_party:fx_freetype",
+      "//third_party/libjpeg_turbo:simd",
+      "//third_party/libsrtp:replay_driver",
+      "//third_party/libsrtp:roc_driver",
+      "//third_party/libsrtp:rtpw",
+      "//third_party/libsrtp:rdbx_driver",
+      "//third_party/libsrtp:srtp_driver",
+      "//third_party/libsrtp:srtp_driver",
+      "//third_party/libsrtp:srtp_test_kernel_driver",
+      "//third_party/libsrtp:srtp_test_cipher_driver",
+      "//third_party/libsrtp:srtp_test_datatypes_driver",
+      "//third_party/libsrtp:srtp_test_aes_calc",
+      "//third_party/libsrtp:srtp_test_env",
+      "//third_party/libsrtp:srtp_test_rand_gen",
+      "//third_party/libsrtp:srtp_test_sha1_driver",
+      "//third_party/libsrtp:srtp_test_stat_driver",
+      "//third_party/opus:opus_compare",
+      "//third_party/opus:opus_demo",
+      "//third_party/opus:test_opus_decode",
+      "//third_party/opus:test_opus_encode",
+      "//third_party/opus:test_opus_api",
+      "//third_party/opus:test_opus_padding",
+      "//third_party/webrtc/system_wrappers:field_trial_default",
+      "//third_party/webrtc/system_wrappers:metrics_default",
+      "//ui/display/types",
+      "//ui/shell_dialogs:shell_dialogs_unittests",
+      "//ui/views/examples:views_examples_exe",
+    ]
+
+    if (target_cpu == "x86" || target_cpu == "x64") {
+      deps += [
+        "//third_party/libjpeg_turbo:simd_asm",
+        "//native_client/src/trusted/platform_qualify:vcpuid",
+      ]
+    }
+    if (enable_nacl) {
+      deps += [ "//native_client/src/trusted/service_runtime:sel_ldr" ]
+    }
+    if (use_ozone) {
+      deps += [ "//ui/ozone/demo" ]
+    }
+    if (is_android) {
+      deps += [ "//build/android/gyp/test:hello_world" ]
+    }
+
+    if (is_linux && current_toolchain == host_toolchain) {
+      deps += [ "//v8:d8" ]
+    }
+  }
+
+  if (is_android) {
+    deps += [ "//blimp" ]
+  }
+
+  if (is_mac) {
+    deps -= [ "//mandoline:all" ]  # TODO(GYP)
+  }
+}
+
+group("gn_mojo_targets") {
+  testonly = true
+  if (is_linux && !is_chromeos) {
+    # TODO(GYP): Figure out if any of these should be in gn_all
+    # and figure out how cross-platform they are
+    deps = [
+      "//ipc/mojo:ipc_mojo_perftests",
+      "//media/mojo/services:cdm_service",
+      "//media/mojo:tests",
+      "//mojo:tests",
+      "//third_party/mojo/src/mojo/edk/js/test:js_integration_tests",
+    ]
+  }
+}
+
+group("gn_visibility") {
+  deps = [
+    "//build/config/sanitizers:options_sources",
+
+    # "//third_party/pdfium:pdfium_embeddertests",  # TODO(GYP): visibility?
+    # "//third_party/pdfium:pdfium_unittests",  # TODO(GYP): visibility?
+
+    "//ui/resources:repack_ui_test_mac_locale_pack",
+  ]
+
+  if (!is_ios) {
+    deps += [
+      "//v8:v8_snapshot",
+      "//v8:postmortem-metadata",
+    ]
+  }
+}
+
+if (!is_ios) {
+  # This group includes all of the targets needed to build and test Blink,
+  # including running the layout tests (see below).
+  group("blink_tests") {
+    testonly = true
+
+    deps = [
+      "//third_party/WebKit/public:all_blink",
+    ]
+
+    # NOTE: The following deps are needed to run the layout tests
+    # (run-webkit-tests) but there is no GN target for the layout tests,
+    # so we need to specify the dependencies here instead.
+    if (is_android) {
+      deps += [
+        "//breakpad:dump_syms($host_toolchain)",
+        "//breakpad:minidump_stackwalk($host_toolchain)",
+        "//content/shell/android:content_shell_apk",
+        "//tools/imagediff($host_toolchain)",
+      ]
+    } else {
+      deps += [
+        "//content/shell:content_shell",
+        "//tools/imagediff",
+      ]
+    }
+
+    if (is_win) {
+      deps += [
+        "//components/test_runner:layout_test_helper",
+        "//content/shell:crash_service",
+      ]
+    }
+
+    if (!is_win && !is_android) {
+      deps += [ "//breakpad:minidump_stackwalk($host_toolchain)" ]
+    }
+
+    if (is_mac) {
+      deps += [
+        "//breakpad:dump_syms($host_toolchain)",
+        "//components/test_runner:layout_test_helper",
+      ]
+    }
+
+    if (is_linux) {
+      deps += [ "//breakpad:dump_syms($host_toolchain)" ]
+    }
+  }
+}
+
+# Add a dummy target for compatibility w/ GYP
+group("chromium_swarm_tests") {
+}
+
+if (is_linux) {
+  # This group corresponds to the list of tests run on the waterfall for
+  # desktop Linux GYP builds from testing/buildbot/chromium.linux.json. It's
+  # here to help track GYP -> GN conversion progress.
+  group("linux_default_tests") {
+    testonly = true
+    deps = [
+      "//base:base_unittests",  # PASSES (*) 2/25/2015
+      "//cc:cc_unittests",  # PASSES 2/25/2015
+      "//chrome/test:browser_tests",
+      "//chrome/test:interactive_ui_tests",
+      "//chrome/test:sync_integration_tests",  # Crashes for brettw in GN and GYP.
+      "//chrome/test:unit_tests",  # PASSES 2/25/2015
+      "//chrome/test/chromedriver:chromedriver_unittests",  # PASSES 2/25/2015
+      "//components:components_browsertests",  # PASSES 4/17/2015
+      "//components:components_unittests",  # PASSES 2/27/2015
+      "//content/test:content_browsertests",
+      "//content/test:content_unittests",  # PASSES 2/25/2015
+      "//crypto:crypto_unittests",  # PASSES 2/25/2015
+      "//dbus:dbus_unittests",  # PASSES 2/25/2015
+      "//device:device_unittests",  # PASSES 3/07/2015
+      "//extensions:extensions_browsertests",  # PASSES 2/25/2015
+      "//extensions:extensions_unittests",  # PASSES 2/25/2015
+      "//extensions/shell:app_shell_unittests",  # PASSES 2/25/2015
+      "//google_apis/gcm:gcm_unit_tests",  # PASSES 2/25/2015
+      "//google_apis:google_apis_unittests",  # PASSES 2/25/2015
+      "//gpu:gpu_unittests",  # PASSES 2/25/2015
+      "//ipc:ipc_tests",  # PASSES 2/25/2015
+      "//ipc/mojo:ipc_mojo_unittests",  # PASSES 2/25/2015
+      "//jingle:jingle_unittests",  # PASSES 2/25/2015
+      "//media:media_unittests",  # PASSES 3/3/2015
+      "//media/cast:cast_unittests",  # PASSES 2/25/2015
+      "//media/midi:midi_unittests",  # PASSES 4/10/2015
+      "//mojo/common:mojo_common_unittests",  # PASSES 2/25/2015
+      "//net:net_unittests",  # PASSES 2/25/2015
+      "//ppapi:ppapi_unittests",  # PASSES 2/26/2015
+      "//printing:printing_unittests",  # PASSES 2/25/2015
+      "//remoting:remoting_unittests",  # PASSES 4/17/2015
+      "//sandbox/linux:sandbox_linux_unittests",  # PASSES 2/25/2015
+      "//skia:skia_unittests",  # PASSES 2/25/2015
+      "//sql:sql_unittests",  # PASSES 2/25/2015
+      "//sync:sync_unit_tests",  # PASSES 2/25/2015
+      "//third_party/cacheinvalidation:cacheinvalidation_unittests",  # PASSES 2/25/2015
+      "//third_party/mojo/src/mojo/edk/system:mojo_system_unittests",  # PASSES 2/25/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_bindings_unittests",  # PASSES 2/25/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_environment_unittests",  # PASSES 2/25/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_system_unittests",  # PASSES 2/25/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_utility_unittests",
+      "//ui/accessibility:accessibility_unittests",  # PASSES 2/25/2015
+      "//ui/app_list:app_list_unittests",  # PASSES 2/25/2015
+      "//ui/aura:aura_unittests",  # PASSES 2/25/2015
+      "//ui/base:ui_base_unittests",  # PASSES 4/17/2015
+      "//ui/compositor:compositor_unittests",  # PASSES 2/25/2015
+      "//ui/display:display_unittests",  # PASSES 2/25/2015
+      "//ui/events:events_unittests",  # PASSES 2/25/2015
+      "//ui/gfx:gfx_unittests",  # PASSES 2/25/2015
+      "//ui/gl:gl_unittests",
+      "//ui/touch_selection:ui_touch_selection_unittests",  # PASSES 2/25/2015
+      "//ui/views:views_unittests",  # PASSES (*) 2/25/2015
+      "//ui/wm:wm_unittests",  # PASSES 2/25/2015
+      "//url:url_unittests",  # PASSES 2/25/2015
+
+      # Note:
+      # (*) Fails but failures match GYP build at time of testing.
+    ]
+
+    if (enable_nacl) {
+      deps += [ "//components/nacl:nacl_loader_unittests" ]  # PASSES 3/28/2015
+    }
+  }
+} else if (is_win) {
+  group("windows_default_tests") {
+    testonly = true
+    deps = [
+      "//ash:ash_unittests",  # FAILS 4/20/2015
+      "//base:base_unittests",  # PASSES 4/20/2015
+      "//cc:cc_unittests",  # PASSES 4/17/2015
+      "//chrome_elf:chrome_elf_unittests",  # FAILS 4/20/2015
+      "//chrome/installer/util:installer_util_unittests",
+      "//chrome/installer/setup:setup_unittests",
+      "//chrome/test:browser_tests",
+      "//chrome/test:interactive_ui_tests",
+      "//chrome/test:sync_integration_tests",  # Note: need to turn off incremental linking for debug.
+      "//chrome/test:unit_tests",
+      "//chrome/test/chromedriver:chromedriver_unittests",  # PASSES 4/20/2015
+      "//components:components_browsertests",  # PASSES 4/24/2015
+      "//components:components_unittests",  # PASSES 4/17/2015
+      "//courgette:courgette_unittests",  # PASSES 4/20/2015
+      "//content/test:content_browsertests",
+      "//content/test:content_unittests",  # PASSES 4/17/2015
+      "//crypto:crypto_unittests",  # PASSES 4/17/2015
+      "//device:device_unittests",  # PASSES 4/17/2015
+      "//extensions:extensions_browsertests",  # PASSES 4/17/2015
+      "//extensions:extensions_unittests",  # PASSES 4/17/2015
+      "//extensions/shell:app_shell_unittests",  # Doesn't compile in 64-bit
+      "//google_apis/gcm:gcm_unit_tests",  # PASSES 4/17/2015
+      "//google_apis:google_apis_unittests",  # PASSES 4/17/2015
+      "//gpu:gpu_unittests",  # PASSES 4/17/2015
+      "//ipc:ipc_tests",  # PASSES 4/17/2015
+      "//ipc/mojo:ipc_mojo_unittests",  # PASSES 4/17/2015
+      "//jingle:jingle_unittests",  # PASSES 4/17/2015
+      "//media/cast:cast_unittests",  # PASSES 4/17/2015
+      "//media:media_unittests",  # PASSES 4/17/2015
+      "//mojo/common:mojo_common_unittests",  # PASSES 4/17/2015
+      "//net:net_unittests",  # PASSES 4/17/2015
+      "//ppapi:ppapi_unittests",  # PASSES 4/17/2015
+      "//printing:printing_unittests",  # PASSES 4/17/2015
+      "//remoting:remoting_unittests",  # PASSES 4/17/2015
+      "//sandbox/win:sbox_integration_tests",  # PASSES 4/20/2015
+      "//sandbox/win:sbox_unittests",  # PASSES 4/20/2015
+      "//sandbox/win:sbox_validation_tests",  # PASSES 4/20/2015
+      "//skia:skia_unittests",  # PASSES 4/17/2015
+      "//sql:sql_unittests",  # PASSES 4/17/2015
+      "//sync:sync_unit_tests",  # PASSES 4/20/2015
+      "//third_party/cacheinvalidation:cacheinvalidation_unittests",  # PASSES 4/20/2015
+      "//third_party/mojo/src/mojo/edk/system:mojo_system_unittests",  # Seems to hang?
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_bindings_unittests",  # FAILS
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_environment_unittests",  # PASSES 4/20/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_system_unittests",  # PASSES 4/20/2015
+      "//third_party/mojo/src/mojo/edk/test:mojo_public_utility_unittests",  # PASSES 4/20/2015
+      "//ui/accessibility:accessibility_unittests",  # PASSES 4/20/2015
+      "//ui/app_list:app_list_unittests",  # PASSES 4/20/2015
+      "//ui/aura:aura_unittests",  # PASSES 4/17/2015
+      "//ui/base:ui_base_unittests",  # PASSES 4/20/2015
+      "//ui/compositor:compositor_unittests",  # PASSES 4/20/2015
+      "//ui/display:display_unittests",  # PASSES 4/20/2015
+      "//ui/events:events_unittests",  # PASSES 4/20/2015
+      "//ui/gfx:gfx_unittests",  # PASSES (with assertion failure?) 4/20/2015
+      "//ui/gl:gl_unittests",
+      "//ui/message_center:message_center_unittests",  # PASSES 4/20/2015
+      "//ui/touch_selection:ui_touch_selection_unittests",  # PASSES 4/20/2015
+      "//ui/views:views_unittests",  # TooltipControllerTest failures
+      "//ui/wm:wm_unittests",  # PASSES 4/21/2015
+      "//url:url_unittests",  # PASSES 4/17/2015
+
+      # TODO(GYP) nacl_integration
+      # TODO(GYP) telemetry_perf_unittests
+      # TODO(GYP) telemetry_unittests
+    ]
+  }
+}
diff --git a/DEPS b/DEPS
new file mode 100644
index 0000000..2759de9
--- /dev/null
+++ b/DEPS
@@ -0,0 +1,811 @@
+# This file is used to manage the dependencies of the Chromium src repo. It is
+# used by gclient to determine what version of each dependency to check out, and
+# where.
+#
+# For more information, please refer to the official documentation:
+#   https://sites.google.com/a/chromium.org/dev/developers/how-tos/get-the-code
+#
+# When adding a new dependency, please update the top-level .gitignore file
+# to list the dependency's destination directory.
+#
+# -----------------------------------------------------------------------------
+# Rolling deps
+# -----------------------------------------------------------------------------
+# All repositories in this file are git-based, using Chromium git mirrors where
+# necessary (e.g., a git mirror is used when the source project is SVN-based).
+# To update the revision that Chromium pulls for a given dependency:
+#
+#  # Create and switch to a new branch
+#  git new-branch depsroll
+#  # Run roll-dep (provided by depot_tools) giving the dep's path and optionally
+#  # a regex that will match the line in this file that contains the current
+#  # revision. The script ALWAYS rolls the dependency to the latest revision
+#  # in origin/master. The path for the dep should start with src/.
+#  roll-dep src/third_party/foo_package/src foo_package.git
+#  # You should now have a modified DEPS file; commit and upload as normal
+#  git commit -a
+#  git cl upload
+
+
+vars = {
+  # Use this googlecode_url variable only if there is an internal mirror for it.
+  # If you do not know, use the full path while defining your new deps entry.
+  'googlecode_url': 'http://%s.googlecode.com/svn',
+  'chromium_git': 'https://chromium.googlesource.com',
+  'libvpx_revision': '0d6551cd1e1359423a7f4af503472d280437e9bb',
+  'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
+  'skia_revision': '10cae83e4bb726610b93276e17815c5d52d73395',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling V8
+  # and whatever else without interference from each other.
+  'v8_revision': '6e4021bb2c08c6948f11a6be4be36f812f9e59a8',
+  # 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': 'f71d1a3fbe207d91bb2f0bd96c8821ff90bb7c28',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling ANGLE
+  # and whatever else without interference from each other.
+  'angle_revision': 'c5b2ba53591c98d5f1c539dc8fcab6f76cc6318e',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling build tools
+  # and whatever else without interference from each other.
+  'buildtools_revision': 'f7310ee61725e68b1c8921e381830362cf4f0999',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling PDFium
+  # and whatever else without interference from each other.
+  'pdfium_revision': 'bca779d0957965eb2ebfad5479e0894844749626',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling openmax_dl
+  # and whatever else without interference from each other.
+  'openmax_dl_revision': '2eb98d819bed3082071a09268b886bc4496c6fb5',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling BoringSSL
+  # and whatever else without interference from each other.
+  'boringssl_revision': '231cb8214511ea5784dd94a59f3e5f5fb7d39f8e',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling nss
+  # and whatever else without interference from each other.
+  'nss_revision': 'aab0d08a298b29407397fbb1c4219f99e99431ed', # from svn revision 295435
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling google-toolbox-for-mac
+  # and whatever else without interference from each other.
+  'google_toolbox_for_mac_revision': 'ce47a231ea0b238fbe95538e86cc61d74c234be6', # from svn revision 705
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling lighttpd
+  # and whatever else without interference from each other.
+  'lighttpd_revision': '9dfa55d15937a688a92cbf2b7a8621b0927d06eb',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling lss
+  # and whatever else without interference from each other.
+  'lss_revision': '4fc942258fe5509549333b9487ec018e3c8c5b10',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling NaCl
+  # and whatever else without interference from each other.
+  'nacl_revision': '719fce7fa0c1f11cf05d5c20cdfa6648e8a35611',
+  # Three lines of non-changing comments so that
+  # the commit queue can handle CLs rolling dEQP
+  # and whatever else without interference from each other.
+  'deqp_revision': '194294e69d44eac48bc1fb063bd607189650aa5e',
+  'deqp_url': 'https://android.googlesource.com/platform/external/deqp',
+}
+
+# Only these hosts are allowed for dependencies in this DEPS file.
+# If you need to add a new host, contact chrome infrastracture team.
+allowed_hosts = [
+  'chromium.googlesource.com',
+  'boringssl.googlesource.com',
+  'pdfium.googlesource.com',
+  'android.googlesource.com',
+]
+
+deps = {
+  'src/breakpad/src':
+   Var('chromium_git') + '/breakpad/breakpad/src.git' + '@' + '027db3c04fbea96f3efa8e1f722ffff11b19a085',
+
+  'src/buildtools':
+   Var('chromium_git') + '/chromium/buildtools.git' + '@' +  Var('buildtools_revision'),
+
+  'src/sdch/open-vcdiff':
+   Var('chromium_git') + '/external/github.com/google/open-vcdiff.git' + '@' + '21d7d0b9c3d0c3ccbdb221c85ae889373f0a2a58',
+
+  'src/testing/gtest':
+   Var('chromium_git') + '/external/googletest.git' + '@' + '9855a87157778d39b95eccfb201a9dc90f6d61c6', # from svn revision 746
+
+  'src/testing/gmock':
+   Var('chromium_git') + '/external/googlemock.git' + '@' + '0421b6f358139f02e102c9c332ce19a33faf75be', # from svn revision 566
+
+  'src/third_party/angle':
+   Var('chromium_git') + '/angle/angle.git' + '@' +  Var('angle_revision'),
+
+  'src/third_party/colorama/src':
+   Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',
+
+  'src/third_party/crashpad/crashpad':
+   Var('chromium_git') + '/crashpad/crashpad.git' + '@' + '595803e1be18aa789ba561aa06db73cfc3c2e7a2',
+
+  'src/third_party/icu':
+   Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '6b3ce817f8e828c3b7a577d2395f0882eb56ef18',
+
+  'src/third_party/libexif/sources':
+   Var('chromium_git') + '/chromium/deps/libexif/sources.git' + '@' + 'ed98343daabd7b4497f97fda972e132e6877c48a',
+
+  'src/third_party/hunspell_dictionaries':
+   Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + 'c106afdcec5d3de2622e19f1b3294c47bbd8bd72',
+
+  'src/third_party/safe_browsing/testing':
+    Var('chromium_git') + '/external/google-safe-browsing/testing.git' + '@' + '9d7e8064f3ca2e45891470c9b5b1dce54af6a9d6',
+
+  'src/third_party/leveldatabase/src':
+    Var('chromium_git') + '/external/leveldb.git' + '@' + '40c17c0b84ac0b791fb434096fd5c05f3819ad55',
+
+  'src/third_party/snappy/src':
+    Var('chromium_git') + '/external/snappy.git' + '@' + '762bb32f0c9d2f31ba4958c7c0933d22e80c20bf',
+
+  'src/tools/grit':
+    Var('chromium_git') + '/external/grit-i18n.git' + '@' + '15d48e32cc9f346245c823ce48c54209d02ea983', # from svn revision 196
+
+  'src/tools/gyp':
+    Var('chromium_git') + '/external/gyp.git' + '@' + '01528c7244837168a1c80f06ff60fa5a9793c824',
+
+  'src/tools/swarming_client':
+   Var('chromium_git') + '/external/swarming.client.git' + '@' +  Var('swarming_revision'),
+
+  'src/v8':
+    Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
+
+  'src/native_client':
+   Var('chromium_git') + '/native_client/src/native_client.git' + '@' + Var('nacl_revision'),
+
+  'src/third_party/sfntly/cpp/src':
+    Var('chromium_git') + '/external/sfntly/cpp/src.git' + '@' +  Var('sfntly_revision'),
+
+  'src/third_party/skia':
+   Var('chromium_git') + '/skia.git' + '@' +  Var('skia_revision'),
+
+  'src/tools/page_cycler/acid3':
+   Var('chromium_git') + '/chromium/deps/acid3.git' + '@' + '6be0a66a1ebd7ebc5abc1b2f405a945f6d871521',
+
+  'src/chrome/test/data/perf/canvas_bench':
+   Var('chromium_git') + '/chromium/canvas_bench.git' + '@' + 'a7b40ea5ae0239517d78845a5fc9b12976bfc732',
+
+  'src/chrome/test/data/perf/frame_rate/content':
+   Var('chromium_git') + '/chromium/frame_rate/content.git' + '@' + 'c10272c88463efeef6bb19c9ec07c42bc8fe22b9',
+
+  'src/third_party/bidichecker':
+    Var('chromium_git') + '/external/bidichecker/lib.git' + '@' + '97f2aa645b74c28c57eca56992235c79850fa9e0',
+
+  'src/third_party/webgl/src':
+   Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '397fdf9245912ce37a01611b7a0ad02cd80de89f',
+
+  'src/third_party/webdriver/pylib':
+    Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
+
+  'src/third_party/libvpx':
+   Var('chromium_git') + '/chromium/deps/libvpx.git' + '@' +  Var('libvpx_revision'),
+
+  'src/third_party/libvpx_new/source/libvpx':
+   Var('chromium_git') + '/webm/libvpx.git' + '@' +  '90a109f0eef8bfaaa4869cf7b2873dac5076b582',
+
+  'src/third_party/ffmpeg':
+   Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '382b031ebab06b25df0708dd44aafad235657d2c',
+
+  'src/third_party/libjingle/source/talk':
+    Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '300c7492bf1d44614047e24a453a1f13a9c9719d', # commit position 10011
+
+  'src/third_party/usrsctp/usrsctplib':
+    Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215
+
+  'src/third_party/libsrtp':
+   Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + '502e81a238a864cfce774d4de3893810629bf227', # from svn revision 295151
+
+  'src/third_party/yasm/source/patched-yasm':
+   Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + '4671120cd8558ce62ee8672ebf3eb6f5216f909b',
+
+  'src/third_party/libjpeg_turbo':
+   Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + 'e4e75037f29745f1546b6ebf5cf532e841c04c2c',
+
+  'src/third_party/flac':
+   Var('chromium_git') + '/chromium/deps/flac.git' + '@' + '2c4b86af352b23498315c016dc207e3fb2733fc0',
+
+  'src/third_party/pyftpdlib/src':
+    Var('chromium_git') + '/external/pyftpdlib.git' + '@' + '2be6d65e31c7ee6320d059f581f05ae8d89d7e45',
+
+  'src/third_party/scons-2.0.1':
+   Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
+
+  'src/third_party/webrtc':
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + 'ea85c10a428fd5f038e969e00833dd4b1a96e1f7', # commit position 10010
+
+  'src/third_party/openmax_dl':
+    Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
+
+  'src/third_party/jsoncpp/source':
+    Var('chromium_git') + '/external/github.com/open-source-parsers/jsoncpp.git' + '@' + 'f572e8e42e22cfcf5ab0aea26574f408943edfa4', # from svn 248
+
+  'src/third_party/libyuv':
+    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '62c49dc811f078e78ed76bfd7c6358c8b7513a14', # from version 1487
+
+  'src/third_party/smhasher/src':
+    Var('chromium_git') + '/external/smhasher.git' + '@' + 'e87738e57558e0ec472b2fc3a643b838e5b6e88f',
+
+  'src/third_party/libaddressinput/src':
+    Var('chromium_git') + '/external/libaddressinput.git' + '@' + '5eeeb797e79fa01503fcdcbebdc50036fac023ef',
+
+  # These are all at libphonenumber r728.
+  'src/third_party/libphonenumber/src/phonenumbers':
+    Var('chromium_git') + '/external/libphonenumber/cpp/src/phonenumbers.git' + '@' + '0d6e3e50e17c94262ad1ca3b7d52b11223084bca',
+  'src/third_party/libphonenumber/src/test':
+    Var('chromium_git') + '/external/libphonenumber/cpp/test.git' + '@' + 'f351a7e007f9c9995494499120bbc361ca808a16',
+  'src/third_party/libphonenumber/src/resources':
+    Var('chromium_git') + '/external/libphonenumber/resources.git' + '@' + 'b6dfdc7952571ff7ee72643cd88c988cbe966396',
+
+  'src/tools/deps2git':
+   Var('chromium_git') + '/chromium/tools/deps2git.git' + '@' + 'f04828eb0b5acd3e7ad983c024870f17f17b06d9',
+
+  'src/third_party/webpagereplay':
+   Var('chromium_git') + '/external/github.com/chromium/web-page-replay.git' + '@' + '7564939bdf6482d57b9bd5e9c931679f96d8cf75',
+
+  'src/third_party/pywebsocket/src':
+    Var('chromium_git') + '/external/github.com/google/pywebsocket.git' + '@' + '09d842794c14ca064f8a4223b313ac2c84bd33c8',
+
+  'src/third_party/opus/src':
+   Var('chromium_git') + '/chromium/deps/opus.git' + '@' + 'cae696156f1e60006e39821e79a1811ae1933c69',
+
+  'src/media/cdm/ppapi/api':
+   Var('chromium_git') + '/chromium/cdm.git' + '@' + '7377023e384f296cbb27644eb2c485275f1f92e8', # from svn revision 294518
+
+  'src/third_party/mesa/src':
+   Var('chromium_git') + '/chromium/deps/mesa.git' + '@' + '3918dbd3bced7843af396a0ee9f9da081d968806',
+
+  'src/third_party/cld_2/src':
+    Var('chromium_git') + '/external/github.com/CLD2Owners/cld2.git' + '@' + '84b58a5d7690ebf05a91406f371ce00c3daf31c0',
+
+  'src/third_party/libwebm/source':
+   Var('chromium_git') + '/webm/libwebm.git' + '@' + '75a6d2da8b63e0c446ec0ce1ac942c2962d959d7',
+
+  'src/third_party/pdfium':
+   'https://pdfium.googlesource.com/pdfium.git' + '@' +  Var('pdfium_revision'),
+
+  'src/third_party/boringssl/src':
+   'https://boringssl.googlesource.com/boringssl.git' + '@' +  Var('boringssl_revision'),
+
+  'src/third_party/py_trace_event/src':
+    Var('chromium_git') + '/external/py_trace_event.git' + '@' + 'dd463ea9e2c430de2b9e53dea57a77b4c3ac9b30',
+
+  'src/third_party/dom_distiller_js/dist':
+    Var('chromium_git') + '/external/github.com/chromium/dom-distiller-dist.git' + '@' + '81e5b59da2a7a0a518b90b5ded58670322c98128',
+
+  'src/third_party/catapult':
+    Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' +
+    '17c9875ee1fe7e078c28450160e7fc08b26fe024',
+}
+
+
+deps_os = {
+  'win': {
+    'src/chrome/tools/test/reference_build/chrome_win':
+     Var('chromium_git') + '/chromium/reference_builds/chrome_win.git' + '@' + 'f8a3a845dfc845df6b14280f04f86a61959357ef',
+
+    'src/third_party/cygwin':
+     Var('chromium_git') + '/chromium/deps/cygwin.git' + '@' + 'c89e446b273697fadf3a10ff1007a97c0b7de6df',
+
+    'src/third_party/psyco_win32':
+     Var('chromium_git') + '/chromium/deps/psyco_win32.git' + '@' + 'f5af9f6910ee5a8075bbaeed0591469f1661d868',
+
+    'src/third_party/bison':
+     Var('chromium_git') + '/chromium/deps/bison.git' + '@' + '083c9a45e4affdd5464ee2b224c2df649c6e26c3',
+
+    'src/third_party/gperf':
+     Var('chromium_git') + '/chromium/deps/gperf.git' + '@' + 'd892d79f64f9449770443fb06da49b5a1e5d33c1',
+
+    'src/third_party/perl':
+     Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
+
+    'src/third_party/lighttpd':
+     Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'),
+
+    # Parses Windows PE/COFF executable format.
+    'src/third_party/pefile':
+     Var('chromium_git') + '/external/pefile.git' + '@' + '72c6ae42396cb913bcab63c15585dc3b5c3f92f1',
+
+    # NSS, for SSLClientSocketNSS.
+    'src/third_party/nss':
+     Var('chromium_git') + '/chromium/deps/nss.git' + '@' + Var('nss_revision'),
+
+    # GNU binutils assembler for x86-32.
+    'src/third_party/gnu_binutils':
+      Var('chromium_git') + '/native_client/deps/third_party/gnu_binutils.git' + '@' + 'f4003433b61b25666565690caf3d7a7a1a4ec436',
+    # GNU binutils assembler for x86-64.
+    'src/third_party/mingw-w64/mingw/bin':
+      Var('chromium_git') + '/native_client/deps/third_party/mingw-w64/mingw/bin.git' + '@' + '3cc8b140b883a9fe4986d12cfd46c16a093d3527',
+
+    # Dependencies used by libjpeg-turbo
+    'src/third_party/yasm/binaries':
+     Var('chromium_git') + '/chromium/deps/yasm/binaries.git' + '@' + '52f9b3f4b0aa06da24ef8b123058bb61ee468881',
+
+    # Binaries for nacl sdk.
+    'src/third_party/nacl_sdk_binaries':
+     Var('chromium_git') + '/chromium/deps/nacl_sdk_binaries.git' + '@' + '759dfca03bdc774da7ecbf974f6e2b84f43699a5',
+
+    # ANGLE uses dEQP for GPU testing
+    'src/third_party/deqp/src':
+     Var('deqp_url') + '@' + Var('deqp_revision'),
+  },
+  'ios': {
+    'src/ios/third_party/gcdwebserver/src':
+     Var('chromium_git') + '/external/github.com/swisspol/GCDWebServer.git' + '@' + '3d5fd0b8281a7224c057deb2d17709b5bea64836',
+
+    'src/third_party/google_toolbox_for_mac/src':
+      Var('chromium_git') + '/external/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
+
+    'src/third_party/nss':
+     Var('chromium_git') + '/chromium/deps/nss.git' + '@' + Var('nss_revision'),
+
+    # class-dump utility to generate header files for undocumented SDKs
+    'src/third_party/class-dump/src':
+     Var('chromium_git') + '/external/github.com/nygard/class-dump.git' + '@' + '978d177ca6f0d2e5e34acf3e8dadc63e3140ebbc',
+
+    # Code that's not needed due to not building everything
+    'src/chrome/test/data/perf/canvas_bench': None,
+    'src/chrome/test/data/perf/frame_rate/content': None,
+    'src/native_client': None,
+    'src/third_party/ffmpeg': None,
+    'src/third_party/hunspell_dictionaries': None,
+    'src/third_party/webgl': None,
+  },
+  'mac': {
+    'src/chrome/tools/test/reference_build/chrome_mac':
+     Var('chromium_git') + '/chromium/reference_builds/chrome_mac.git' + '@' + '8dc181329e7c5255f83b4b85dc2f71498a237955',
+
+    'src/third_party/google_toolbox_for_mac/src':
+      Var('chromium_git') + '/external/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
+
+
+    'src/third_party/pdfsqueeze':
+      Var('chromium_git') + '/external/pdfsqueeze.git' + '@' + '5936b871e6a087b7e50d4cbcb122378d8a07499f',
+
+    'src/third_party/lighttpd':
+     Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'),
+
+    # NSS, for SSLClientSocketNSS.
+    'src/third_party/nss':
+     Var('chromium_git') + '/chromium/deps/nss.git' + '@' + Var('nss_revision'),
+
+    'src/chrome/installer/mac/third_party/xz/xz':
+     Var('chromium_git') + '/chromium/deps/xz.git' + '@' + 'eecaf55632ca72e90eb2641376bce7cdbc7284f7',
+  },
+  'unix': {
+    # Linux, really.
+    'src/chrome/tools/test/reference_build/chrome_linux':
+     Var('chromium_git') + '/chromium/reference_builds/chrome_linux64.git' + '@' + '033d053a528e820e1de3e2db766678d862a86b36',
+
+    'src/third_party/xdg-utils':
+     Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
+
+    'src/third_party/lss':
+      Var('chromium_git') + '/external/linux-syscall-support/lss.git' + '@' + Var('lss_revision'),
+
+    # For Linux and Chromium OS.
+    'src/third_party/cros_system_api':
+     Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '0b175578c8150c7ee0e7e4fd6d4dc7480979e248',
+
+    # Note that this is different from Android's freetype repo.
+    'src/third_party/freetype2/src':
+     Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + 'fc1532a7c4c592f24a4c1a0261d2845524ca5cff',
+
+    # Build tools for Chrome OS.
+    'src/third_party/chromite':
+     Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'e19f83ba227bf1ec0077f5d3a816a415f1dd88d0',
+
+    # Dependency of chromite.git.
+    'src/third_party/pyelftools':
+     Var('chromium_git') + '/chromiumos/third_party/pyelftools.git' + '@' + 'bdc1d380acd88d4bfaf47265008091483b0d614e',
+
+    'src/third_party/liblouis/src':
+     Var('chromium_git') + '/external/liblouis-github.git' + '@' + '5f9c03f2a3478561deb6ae4798175094be8a26c2',
+
+    # Used for embedded builds. CrOS & Linux use the system version.
+    'src/third_party/fontconfig/src':
+     Var('chromium_git') + '/external/fontconfig.git' + '@' + 'f16c3118e25546c1b749f9823c51827a60aeb5c1',
+
+    # ANGLE uses dEQP for GPU testing
+    'src/third_party/deqp/src':
+     Var('deqp_url') + '@' + Var('deqp_revision'),
+
+    # Graphics buffer allocator for Chrome OS.
+    'src/third_party/minigbm/src':
+     Var('chromium_git') + '/chromiumos/platform/minigbm.git' + '@' + 'f9d2ab79a15a1bb6a1307f3b608964c81c27791b',
+  },
+  'android': {
+    'src/third_party/android_protobuf/src':
+     Var('chromium_git') + '/external/android_protobuf.git' + '@' + '999188d0dc72e97f7fe08bb756958a2cf090f4e7',
+
+    'src/third_party/android_tools':
+     Var('chromium_git') + '/android_tools.git' + '@' + '4238a28593b7e6178c95431f91ca8c24e45fa7eb',
+
+    'src/third_party/apache-mime4j':
+     Var('chromium_git') + '/chromium/deps/apache-mime4j.git' + '@' + '28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',
+
+    'src/third_party/appurify-python/src':
+     Var('chromium_git') + '/external/github.com/appurify/appurify-python.git' + '@' + 'ee7abd5c5ae3106f72b2a0b9d2cb55094688e867',
+
+    'src/third_party/cardboard-java/src':
+     Var('chromium_git') + '/external/github.com/googlesamples/cardboard-java.git' + '@' + 'e36ee57e72bbd057ddb53b127954177b50e18df7',
+
+    'src/third_party/errorprone/lib':
+      Var('chromium_git') + '/chromium/third_party/errorprone.git' + '@' + '95f929ff6f9213bc7d078c200db3f3dc864f425f',
+
+    'src/third_party/findbugs':
+     Var('chromium_git') + '/chromium/deps/findbugs.git' + '@' + '57f05238d3ac77ea0a194813d3065dd780c6e566',
+
+    'src/third_party/freetype-android/src':
+     Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + 'e186230678ee8e4ea4ac4797ece8125761e3225a',
+
+   'src/third_party/elfutils/src':
+     Var('chromium_git') + '/external/elfutils.git' + '@' + '249673729a7e5dbd5de4f3760bdcaa3d23d154d7',
+
+    'src/third_party/httpcomponents-client':
+     Var('chromium_git') + '/chromium/deps/httpcomponents-client.git' + '@' + '285c4dafc5de0e853fa845dce5773e223219601c',
+
+    'src/third_party/httpcomponents-core':
+     Var('chromium_git') + '/chromium/deps/httpcomponents-core.git' + '@' + '9f7180a96f8fa5cab23f793c14b413356d419e62',
+
+    'src/third_party/jarjar':
+     Var('chromium_git') + '/chromium/deps/jarjar.git' + '@' + '2e1ead4c68c450e0b77fe49e3f9137842b8b6920',
+
+    'src/third_party/jsr-305/src':
+      Var('chromium_git') + '/external/jsr-305.git' + '@' + '642c508235471f7220af6d5df2d3210e3bfc0919',
+
+    'src/third_party/junit/src':
+      Var('chromium_git') + '/external/junit.git' + '@' + '45a44647e7306262162e1346b750c3209019f2e1',
+
+    'src/third_party/mockito/src':
+      Var('chromium_git') + '/external/mockito/mockito.git' + '@' + '4d987dcd923b81525c42b1333e6c4e07440776c3',
+
+    'src/third_party/robolectric/lib':
+      Var('chromium_git') + '/chromium/third_party/robolectric.git' + '@' + '6b63c99a8b6967acdb42cbed0adb067c80efc810',
+
+    'src/third_party/ub-uiautomator/lib':
+      Var('chromium_git') + '/chromium/third_party/ub-uiautomator.git' + '@' + '00270549ce3161ae72ceb24712618ea28b4f9434',
+
+    'src/third_party/lss':
+      Var('chromium_git') + '/external/linux-syscall-support/lss.git' + '@' + Var('lss_revision'),
+
+    'src/third_party/requests/src':
+      Var('chromium_git') + '/external/github.com/kennethreitz/requests.git' + '@' + 'f172b30356d821d180fa4ecfa3e71c7274a32de4',
+
+    'src/third_party/custom_tabs_client/src':
+      Var('chromium_git') + '/external/github.com/GoogleChrome/custom-tabs-client.git' + '@' + 'bbbf71f41e79b0cfe21199220f495cbd0a3a4ffb',
+  },
+}
+
+
+include_rules = [
+  # Everybody can use some things.
+  # NOTE: THIS HAS TO STAY IN SYNC WITH third_party/DEPS which disallows these.
+  '+base',
+  '+build',
+  '+ipc',
+
+  # Everybody can use headers generated by tools/generate_library_loader.
+  '+library_loaders',
+
+  '+testing',
+  '+third_party/icu/source/common/unicode',
+  '+third_party/icu/source/i18n/unicode',
+  '+url',
+]
+
+
+# checkdeps.py shouldn't check include paths for files in these dirs:
+skip_child_includes = [
+  'breakpad',
+  'native_client_sdk',
+  'out',
+  'sdch',
+  'skia',
+  'testing',
+  'v8',
+  'win8',
+]
+
+
+hooks = [
+  {
+    # This clobbers when necessary (based on get_landmines.py). It must be the
+    # first hook so that other things that get/generate into the output
+    # directory will not subsequently be clobbered.
+    'name': 'landmines',
+    'pattern': '.',
+    'action': [
+        'python',
+        'src/build/landmines.py',
+    ],
+  },
+  {
+    # This downloads binaries for Native Client's newlib toolchain.
+    # Done in lieu of building the toolchain from scratch as it can take
+    # anywhere from 30 minutes to 4 hours depending on platform to build.
+    'name': 'nacltools',
+    'pattern': '.',
+    'action': [
+        'python',
+        'src/build/download_nacl_toolchains.py',
+        '--mode', 'nacl_core_sdk',
+        'sync', '--extract',
+    ],
+  },
+  {
+    # This downloads SDK extras and puts them in the
+    # third_party/android_tools/sdk/extras directory on the bots. Developers
+    # need to manually install these packages and accept the ToS.
+    'name': 'sdkextras',
+    'pattern': '.',
+    # When adding a new sdk extras package to download, add the package
+    # directory and zip file to .gitignore in third_party/android_tools.
+    'action': ['python', 'src/build/download_sdk_extras.py'],
+  },
+  {
+    # Downloads the current stable linux sysroot to build/linux/ if needed.
+    # This sysroot updates at about the same rate that the chrome build deps
+    # change. This script is a no-op except for linux users who are doing
+    # official chrome builds or cross compiling.
+    'name': 'sysroot',
+    'pattern': '.',
+    'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
+               '--running-as-hook'],
+  },
+  {
+    # Update the Windows toolchain if necessary.
+    'name': 'win_toolchain',
+    'pattern': '.',
+    'action': ['python', 'src/build/vs_toolchain.py', 'update'],
+  },
+  # Pull binutils for linux, enabled debug fission for faster linking /
+  # debugging when used with clang on Ubuntu Precise.
+  # https://code.google.com/p/chromium/issues/detail?id=352046
+  {
+    'name': 'binutils',
+    'pattern': 'src/third_party/binutils',
+    'action': [
+        'python',
+        'src/third_party/binutils/download.py',
+    ],
+  },
+  {
+    # Pull clang if needed or requested via GYP_DEFINES.
+    # Note: On Win, this should run after win_toolchain, as it may use it.
+    'name': 'clang',
+    'pattern': '.',
+    'action': ['python', 'src/tools/clang/scripts/update.py', '--if-needed'],
+  },
+  {
+    # Update LASTCHANGE.
+    'name': 'lastchange',
+    'pattern': '.',
+    'action': ['python', 'src/build/util/lastchange.py',
+               '-o', 'src/build/util/LASTCHANGE'],
+  },
+  {
+    # Update LASTCHANGE.blink.
+    'name': 'lastchange',
+    'pattern': '.',
+    'action': ['python', 'src/build/util/lastchange.py',
+               '-s', 'src/third_party/WebKit',
+               '-o', 'src/build/util/LASTCHANGE.blink'],
+  },
+  {
+    # Update CANARY_VERSION.
+    'name': 'ios_canary_version',
+    'pattern': '.',
+    'action': ['python', 'src/ios/build/util/canary_version.py',
+               '-o', 'src/ios/build/util/CANARY_VERSION'],
+  },
+  # Pull GN binaries. This needs to be before running GYP below.
+  {
+    'name': 'gn_win',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=win32',
+                '--no_auth',
+                '--bucket', 'chromium-gn',
+                '-s', 'src/buildtools/win/gn.exe.sha1',
+    ],
+  },
+  {
+    'name': 'gn_mac',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=darwin',
+                '--no_auth',
+                '--bucket', 'chromium-gn',
+                '-s', 'src/buildtools/mac/gn.sha1',
+    ],
+  },
+  {
+    'name': 'gn_linux64',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=linux*',
+                '--no_auth',
+                '--bucket', 'chromium-gn',
+                '-s', 'src/buildtools/linux64/gn.sha1',
+    ],
+  },
+  # Pull clang-format binaries using checked-in hashes.
+  {
+    'name': 'clang_format_win',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=win32',
+                '--no_auth',
+                '--bucket', 'chromium-clang-format',
+                '-s', 'src/buildtools/win/clang-format.exe.sha1',
+    ],
+  },
+  {
+    'name': 'clang_format_mac',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=darwin',
+                '--no_auth',
+                '--bucket', 'chromium-clang-format',
+                '-s', 'src/buildtools/mac/clang-format.sha1',
+    ],
+  },
+  {
+    'name': 'clang_format_linux',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=linux*',
+                '--no_auth',
+                '--bucket', 'chromium-clang-format',
+                '-s', 'src/buildtools/linux64/clang-format.sha1',
+    ],
+  },
+  # Pull luci-go binaries (isolate, swarming) using checked-in hashes.
+  {
+    'name': 'luci-go_win',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=win32',
+                '--no_auth',
+                '--bucket', 'chromium-luci',
+                '-d', 'src/tools/luci-go/win64',
+    ],
+  },
+  {
+    'name': 'luci-go_mac',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=darwin',
+                '--no_auth',
+                '--bucket', 'chromium-luci',
+                '-d', 'src/tools/luci-go/mac64',
+    ],
+  },
+  {
+    'name': 'luci-go_linux',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=linux*',
+                '--no_auth',
+                '--bucket', 'chromium-luci',
+                '-d', 'src/tools/luci-go/linux64',
+    ],
+  },
+  # Pull eu-strip binaries using checked-in hashes.
+  {
+    'name': 'eu-strip',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=linux*',
+                '--no_auth',
+                '--bucket', 'chromium-eu-strip',
+                '-s', 'src/build/linux/bin/eu-strip.sha1',
+    ],
+  },
+  {
+    'name': 'drmemory',
+    'pattern': '.',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=win32',
+                '--no_auth',
+                '--bucket', 'chromium-drmemory',
+                '-s', 'src/third_party/drmemory/drmemory-windows-sfx.exe.sha1',
+              ],
+  },
+  # Pull the Syzygy binaries, used for optimization and instrumentation.
+  {
+    'name': 'syzygy-binaries',
+    'pattern': '.',
+    'action': ['python',
+               'src/build/get_syzygy_binaries.py',
+               '--output-dir=src/third_party/syzygy/binaries',
+               '--revision=8341560b55cebb58351b56bcb809bbbe22ca5398',
+               '--overwrite',
+    ],
+  },
+  {
+    'name': 'kasko',
+    'pattern': '.',
+    'action': ['python',
+               'src/build/get_syzygy_binaries.py',
+               '--output-dir=src/third_party/kasko',
+               '--revision=56f13b37f044639b4c28cb75f327ca5e3db8758e',
+               '--resource=kasko.zip',
+               '--resource=kasko_symbols.zip',
+               '--overwrite',
+    ],
+  },
+  {
+    'name': 'apache_win32',
+    'pattern': '\\.sha1',
+    'action': [ 'download_from_google_storage',
+                '--no_resume',
+                '--platform=win32',
+                '--directory',
+                '--recursive',
+                '--no_auth',
+                '--num_threads=16',
+                '--bucket', 'chromium-apache-win32',
+                'src/third_party/apache-win32',
+    ],
+  },
+  {
+    # Pull sanitizer-instrumented third-party libraries if requested via
+    # GYP_DEFINES.
+    'name': 'instrumented_libraries',
+    'pattern': '\\.sha1',
+    'action': ['python', 'src/third_party/instrumented_libraries/scripts/download_binaries.py'],
+  },
+  {
+    # Ensure that while generating dependencies lists in .gyp files we don't
+    # accidentally reference any .pyc files whose corresponding .py files have
+    # already been deleted.
+    # We should actually try to avoid generating .pyc files, crbug.com/500078.
+    'name': 'remove_stale_pyc_files',
+    'pattern': '.',
+    'action': [
+        'python',
+        'src/tools/remove_stale_pyc_files.py',
+        'src/android_webview/tools',
+        'src/gpu/gles2_conform_support',
+        'src/infra',
+        'src/ppapi',
+        'src/printing',
+        'src/third_party/closure_compiler/build',
+        'src/tools',
+    ],
+  },
+  {
+    # A change to a .gyp, .gypi, or to GYP itself should run the generator.
+    'name': 'gyp',
+    'pattern': '.',
+    'action': ['python', 'src/build/gyp_chromium'],
+  },
+  {
+    # Verify committers' ~/.netc, gclient and git are properly configured for
+    # write access to the git repo. To be removed sometime after Chrome to git
+    # migration completes (let's say Sep 1 2014).
+    'name': 'check_git_config',
+    'pattern': '.',
+    'action': [
+        'python',
+        'src/tools/check_git_config.py',
+        '--running-as-hook',
+    ],
+  },
+]
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a32e00c
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/LICENSE.chromium_os b/LICENSE.chromium_os
new file mode 100644
index 0000000..0aa7fc9
--- /dev/null
+++ b/LICENSE.chromium_os
@@ -0,0 +1,27 @@
+// Copyright (c) 2006-2009 The Chromium OS Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..5c3e10b
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,13 @@
+ben@chromium.org
+brettw@chromium.org
+cpu@chromium.org
+darin@chromium.org
+jam@chromium.org
+
+per-file .gitignore=*
+per-file BUILD.gn=dpranke@chromium.org
+per-file DEPS=*
+per-file AUTHORS=*
+per-file WATCHLISTS=*
+per-file PRESUBMIT*.py=jochen@chromium.org
+per-file PRESUBMIT*.py=phajdan.jr@chromium.org
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
new file mode 100644
index 0000000..c777fb8
--- /dev/null
+++ b/PRESUBMIT.py
@@ -0,0 +1,1937 @@
+# 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.
+
+"""Top-level presubmit script for Chromium.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into depot_tools.
+"""
+
+
+_EXCLUDED_PATHS = (
+    r"^breakpad[\\\/].*",
+    r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_rules.py",
+    r"^native_client_sdk[\\\/]src[\\\/]build_tools[\\\/]make_simple.py",
+    r"^native_client_sdk[\\\/]src[\\\/]tools[\\\/].*.mk",
+    r"^net[\\\/]tools[\\\/]spdyshark[\\\/].*",
+    r"^skia[\\\/].*",
+    r"^v8[\\\/].*",
+    r".*MakeFile$",
+    r".+_autogen\.h$",
+    r".+[\\\/]pnacl_shim\.c$",
+    r"^gpu[\\\/]config[\\\/].*_list_json\.cc$",
+    r"^chrome[\\\/]browser[\\\/]resources[\\\/]pdf[\\\/]index.js"
+)
+
+# The NetscapePlugIn library is excluded from pan-project as it will soon
+# be deleted together with the rest of the NPAPI and it's not worthwhile to
+# update the coding style until then.
+_TESTRUNNER_PATHS = (
+    r"^content[\\\/]shell[\\\/]tools[\\\/]plugin[\\\/].*",
+)
+
+# Fragment of a regular expression that matches C++ and Objective-C++
+# implementation files.
+_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
+
+# Regular expression that matches code only used for test binaries
+# (best effort).
+_TEST_CODE_EXCLUDED_PATHS = (
+    r'.*[\\\/](fake_|test_|mock_).+%s' % _IMPLEMENTATION_EXTENSIONS,
+    r'.+_test_(base|support|util)%s' % _IMPLEMENTATION_EXTENSIONS,
+    r'.+_(api|browser|kif|perf|pixel|unit|ui)?test(_[a-z]+)?%s' %
+        _IMPLEMENTATION_EXTENSIONS,
+    r'.+profile_sync_service_harness%s' % _IMPLEMENTATION_EXTENSIONS,
+    r'.*[\\\/](test|tool(s)?)[\\\/].*',
+    # content_shell is used for running layout tests.
+    r'content[\\\/]shell[\\\/].*',
+    # At request of folks maintaining this folder.
+    r'chrome[\\\/]browser[\\\/]automation[\\\/].*',
+    # Non-production example code.
+    r'mojo[\\\/]examples[\\\/].*',
+    # Launcher for running iOS tests on the simulator.
+    r'testing[\\\/]iossim[\\\/]iossim\.mm$',
+)
+
+_TEST_ONLY_WARNING = (
+    'You might be calling functions intended only for testing from\n'
+    'production code.  It is OK to ignore this warning if you know what\n'
+    'you are doing, as the heuristics used to detect the situation are\n'
+    'not perfect.  The commit queue will not block on this warning.')
+
+
+_INCLUDE_ORDER_WARNING = (
+    'Your #include order seems to be broken. Remember to use the right '
+    'collation (LC_COLLATE=C) and check\nhttps://google-styleguide.googlecode'
+    '.com/svn/trunk/cppguide.html#Names_and_Order_of_Includes')
+
+_BANNED_OBJC_FUNCTIONS = (
+    (
+      'addTrackingRect:',
+      (
+       'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
+       'prohibited. Please use CrTrackingArea instead.',
+       'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
+      ),
+      False,
+    ),
+    (
+      r'/NSTrackingArea\W',
+      (
+       'The use of NSTrackingAreas is prohibited. Please use CrTrackingArea',
+       'instead.',
+       'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
+      ),
+      False,
+    ),
+    (
+      'convertPointFromBase:',
+      (
+       'The use of -[NSView convertPointFromBase:] is almost certainly wrong.',
+       'Please use |convertPoint:(point) fromView:nil| instead.',
+       'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
+      ),
+      True,
+    ),
+    (
+      'convertPointToBase:',
+      (
+       'The use of -[NSView convertPointToBase:] is almost certainly wrong.',
+       'Please use |convertPoint:(point) toView:nil| instead.',
+       'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
+      ),
+      True,
+    ),
+    (
+      'convertRectFromBase:',
+      (
+       'The use of -[NSView convertRectFromBase:] is almost certainly wrong.',
+       'Please use |convertRect:(point) fromView:nil| instead.',
+       'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
+      ),
+      True,
+    ),
+    (
+      'convertRectToBase:',
+      (
+       'The use of -[NSView convertRectToBase:] is almost certainly wrong.',
+       'Please use |convertRect:(point) toView:nil| instead.',
+       'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
+      ),
+      True,
+    ),
+    (
+      'convertSizeFromBase:',
+      (
+       'The use of -[NSView convertSizeFromBase:] is almost certainly wrong.',
+       'Please use |convertSize:(point) fromView:nil| instead.',
+       'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
+      ),
+      True,
+    ),
+    (
+      'convertSizeToBase:',
+      (
+       'The use of -[NSView convertSizeToBase:] is almost certainly wrong.',
+       'Please use |convertSize:(point) toView:nil| instead.',
+       'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
+      ),
+      True,
+    ),
+)
+
+
+_BANNED_CPP_FUNCTIONS = (
+    # Make sure that gtest's FRIEND_TEST() macro is not used; the
+    # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be
+    # used instead since that allows for FLAKY_ and DISABLED_ prefixes.
+    (
+      'FRIEND_TEST(',
+      (
+       'Chromium code should not use gtest\'s FRIEND_TEST() macro. Include',
+       'base/gtest_prod_util.h and use FRIEND_TEST_ALL_PREFIXES() instead.',
+      ),
+      False,
+      (),
+    ),
+    (
+      'ScopedAllowIO',
+      (
+       'New code should not use ScopedAllowIO. Post a task to the blocking',
+       'pool or the FILE thread instead.',
+      ),
+      True,
+      (
+        r"^base[\\\/]process[\\\/]process_metrics_linux\.cc$",
+        r"^chrome[\\\/]browser[\\\/]chromeos[\\\/]boot_times_recorder\.cc$",
+        r"^chrome[\\\/]browser[\\\/]chromeos[\\\/]"
+            "customization_document_browsertest\.cc$",
+        r"^components[\\\/]crash[\\\/]app[\\\/]breakpad_mac\.mm$",
+        r"^content[\\\/]shell[\\\/]browser[\\\/]shell_browser_main\.cc$",
+        r"^content[\\\/]shell[\\\/]browser[\\\/]shell_message_filter\.cc$",
+        r"^mojo[\\\/]edk[\\\/]embedder[\\\/]" +
+            r"simple_platform_shared_buffer_posix\.cc$",
+        r"^net[\\\/]disk_cache[\\\/]cache_util\.cc$",
+        r"^net[\\\/]url_request[\\\/]test_url_fetcher_factory\.cc$",
+        r"^remoting[\\\/]host[\\\/]gnubby_auth_handler_posix\.cc$",
+        r"^ui[\\\/]ozone[\\\/]platform[\\\/]drm[\\\/]host[\\\/]"
+            "drm_display_host_manager\.cc$",
+      ),
+    ),
+    (
+      'SkRefPtr',
+      (
+        'The use of SkRefPtr is prohibited. ',
+        'Please use skia::RefPtr instead.'
+      ),
+      True,
+      (),
+    ),
+    (
+      'SkAutoRef',
+      (
+        'The indirect use of SkRefPtr via SkAutoRef is prohibited. ',
+        'Please use skia::RefPtr instead.'
+      ),
+      True,
+      (),
+    ),
+    (
+      'SkAutoTUnref',
+      (
+        'The use of SkAutoTUnref is dangerous because it implicitly ',
+        'converts to a raw pointer. Please use skia::RefPtr instead.'
+      ),
+      True,
+      (),
+    ),
+    (
+      'SkAutoUnref',
+      (
+        'The indirect use of SkAutoTUnref through SkAutoUnref is dangerous ',
+        'because it implicitly converts to a raw pointer. ',
+        'Please use skia::RefPtr instead.'
+      ),
+      True,
+      (),
+    ),
+    (
+      r'/HANDLE_EINTR\(.*close',
+      (
+       'HANDLE_EINTR(close) is invalid. If close fails with EINTR, the file',
+       'descriptor will be closed, and it is incorrect to retry the close.',
+       'Either call close directly and ignore its return value, or wrap close',
+       'in IGNORE_EINTR to use its return value. See http://crbug.com/269623'
+      ),
+      True,
+      (),
+    ),
+    (
+      r'/IGNORE_EINTR\((?!.*close)',
+      (
+       'IGNORE_EINTR is only valid when wrapping close. To wrap other system',
+       'calls, use HANDLE_EINTR. See http://crbug.com/269623',
+      ),
+      True,
+      (
+        # Files that #define IGNORE_EINTR.
+        r'^base[\\\/]posix[\\\/]eintr_wrapper\.h$',
+        r'^ppapi[\\\/]tests[\\\/]test_broker\.cc$',
+      ),
+    ),
+    (
+      r'/v8::Extension\(',
+      (
+        'Do not introduce new v8::Extensions into the code base, use',
+        'gin::Wrappable instead. See http://crbug.com/334679',
+      ),
+      True,
+      (
+        r'extensions[\\\/]renderer[\\\/]safe_builtins\.*',
+      ),
+    ),
+    (
+      '\<MessageLoopProxy\>',
+      (
+        'MessageLoopProxy is deprecated. ',
+        'Please use SingleThreadTaskRunner or ThreadTaskRunnerHandle instead.'
+      ),
+      True,
+      (
+        # Internal message_loop related code may still use it.
+        r'^base[\\\/]message_loop[\\\/].*',
+      ),
+    ),
+)
+
+_IPC_ENUM_TRAITS_DEPRECATED = (
+    'You are using IPC_ENUM_TRAITS() in your code. It has been deprecated.\n'
+    'See http://www.chromium.org/Home/chromium-security/education/security-tips-for-ipc')
+
+
+_VALID_OS_MACROS = (
+    # Please keep sorted.
+    'OS_ANDROID',
+    'OS_ANDROID_HOST',
+    'OS_BSD',
+    'OS_CAT',       # For testing.
+    'OS_CHROMEOS',
+    'OS_FREEBSD',
+    'OS_IOS',
+    'OS_LINUX',
+    'OS_MACOSX',
+    'OS_NACL',
+    'OS_NACL_NONSFI',
+    'OS_NACL_SFI',
+    'OS_OPENBSD',
+    'OS_POSIX',
+    'OS_QNX',
+    'OS_SOLARIS',
+    'OS_WIN',
+)
+
+
+def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
+  """Attempts to prevent use of functions intended only for testing in
+  non-testing code. For now this is just a best-effort implementation
+  that ignores header files and may have some false positives. A
+  better implementation would probably need a proper C++ parser.
+  """
+  # We only scan .cc files and the like, as the declaration of
+  # for-testing functions in header files are hard to distinguish from
+  # calls to such functions without a proper C++ parser.
+  file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
+
+  base_function_pattern = r'[ :]test::[^\s]+|ForTest(s|ing)?|for_test(s|ing)?'
+  inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
+  comment_pattern = input_api.re.compile(r'//.*(%s)' % base_function_pattern)
+  exclusion_pattern = input_api.re.compile(
+    r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
+      base_function_pattern, base_function_pattern))
+
+  def FilterFile(affected_file):
+    black_list = (_EXCLUDED_PATHS +
+                  _TEST_CODE_EXCLUDED_PATHS +
+                  input_api.DEFAULT_BLACK_LIST)
+    return input_api.FilterSourceFile(
+      affected_file,
+      white_list=(file_inclusion_pattern, ),
+      black_list=black_list)
+
+  problems = []
+  for f in input_api.AffectedSourceFiles(FilterFile):
+    local_path = f.LocalPath()
+    for line_number, line in f.ChangedContents():
+      if (inclusion_pattern.search(line) and
+          not comment_pattern.search(line) and
+          not exclusion_pattern.search(line)):
+        problems.append(
+          '%s:%d\n    %s' % (local_path, line_number, line.strip()))
+
+  if problems:
+    return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)]
+  else:
+    return []
+
+
+def _CheckNoIOStreamInHeaders(input_api, output_api):
+  """Checks to make sure no .h files include <iostream>."""
+  files = []
+  pattern = input_api.re.compile(r'^#include\s*<iostream>',
+                                 input_api.re.MULTILINE)
+  for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
+    if not f.LocalPath().endswith('.h'):
+      continue
+    contents = input_api.ReadFile(f)
+    if pattern.search(contents):
+      files.append(f)
+
+  if len(files):
+    return [ output_api.PresubmitError(
+        'Do not #include <iostream> in header files, since it inserts static '
+        'initialization into every file including the header. Instead, '
+        '#include <ostream>. See http://crbug.com/94794',
+        files) ]
+  return []
+
+
+def _CheckNoUNIT_TESTInSourceFiles(input_api, output_api):
+  """Checks to make sure no source files use UNIT_TEST"""
+  problems = []
+  for f in input_api.AffectedFiles():
+    if (not f.LocalPath().endswith(('.cc', '.mm'))):
+      continue
+
+    for line_num, line in f.ChangedContents():
+      if 'UNIT_TEST ' in line or line.endswith('UNIT_TEST'):
+        problems.append('    %s:%d' % (f.LocalPath(), line_num))
+
+  if not problems:
+    return []
+  return [output_api.PresubmitPromptWarning('UNIT_TEST is only for headers.\n' +
+      '\n'.join(problems))]
+
+
+def _FindHistogramNameInLine(histogram_name, line):
+  """Tries to find a histogram name or prefix in a line."""
+  if not "affected-histogram" in line:
+    return histogram_name in line
+  # A histogram_suffixes tag type has an affected-histogram name as a prefix of
+  # the histogram_name.
+  if not '"' in line:
+    return False
+  histogram_prefix = line.split('\"')[1]
+  return histogram_prefix in histogram_name
+
+
+def _CheckUmaHistogramChanges(input_api, output_api):
+  """Check that UMA histogram names in touched lines can still be found in other
+  lines of the patch or in histograms.xml. Note that this check would not catch
+  the reverse: changes in histograms.xml not matched in the code itself."""
+  touched_histograms = []
+  histograms_xml_modifications = []
+  pattern = input_api.re.compile('UMA_HISTOGRAM.*\("(.*)"')
+  for f in input_api.AffectedFiles():
+    # If histograms.xml itself is modified, keep the modified lines for later.
+    if f.LocalPath().endswith(('histograms.xml')):
+      histograms_xml_modifications = f.ChangedContents()
+      continue
+    if not f.LocalPath().endswith(('cc', 'mm', 'cpp')):
+      continue
+    for line_num, line in f.ChangedContents():
+      found = pattern.search(line)
+      if found:
+        touched_histograms.append([found.group(1), f, line_num])
+
+  # Search for the touched histogram names in the local modifications to
+  # histograms.xml, and, if not found, on the base histograms.xml file.
+  unmatched_histograms = []
+  for histogram_info in touched_histograms:
+    histogram_name_found = False
+    for line_num, line in histograms_xml_modifications:
+      histogram_name_found = _FindHistogramNameInLine(histogram_info[0], line)
+      if histogram_name_found:
+        break
+    if not histogram_name_found:
+      unmatched_histograms.append(histogram_info)
+
+  histograms_xml_path = 'tools/metrics/histograms/histograms.xml'
+  problems = []
+  if unmatched_histograms:
+    with open(histograms_xml_path) as histograms_xml:
+      for histogram_name, f, line_num in unmatched_histograms:
+        histograms_xml.seek(0)
+        histogram_name_found = False
+        for line in histograms_xml:
+          histogram_name_found = _FindHistogramNameInLine(histogram_name, line)
+          if histogram_name_found:
+            break
+        if not histogram_name_found:
+          problems.append(' [%s:%d] %s' %
+                          (f.LocalPath(), line_num, histogram_name))
+
+  if not problems:
+    return []
+  return [output_api.PresubmitPromptWarning('Some UMA_HISTOGRAM lines have '
+    'been modified and the associated histogram name has no match in either '
+    '%s or the modifications of it:' % (histograms_xml_path),  problems)]
+
+
+def _CheckNoNewWStrings(input_api, output_api):
+  """Checks to make sure we don't introduce use of wstrings."""
+  problems = []
+  for f in input_api.AffectedFiles():
+    if (not f.LocalPath().endswith(('.cc', '.h')) or
+        f.LocalPath().endswith(('test.cc', '_win.cc', '_win.h')) or
+        '/win/' in f.LocalPath()):
+      continue
+
+    allowWString = False
+    for line_num, line in f.ChangedContents():
+      if 'presubmit: allow wstring' in line:
+        allowWString = True
+      elif not allowWString and 'wstring' in line:
+        problems.append('    %s:%d' % (f.LocalPath(), line_num))
+        allowWString = False
+      else:
+        allowWString = False
+
+  if not problems:
+    return []
+  return [output_api.PresubmitPromptWarning('New code should not use wstrings.'
+      '  If you are calling a cross-platform API that accepts a wstring, '
+      'fix the API.\n' +
+      '\n'.join(problems))]
+
+
+def _CheckNoDEPSGIT(input_api, output_api):
+  """Make sure .DEPS.git is never modified manually."""
+  if any(f.LocalPath().endswith('.DEPS.git') for f in
+      input_api.AffectedFiles()):
+    return [output_api.PresubmitError(
+      'Never commit changes to .DEPS.git. This file is maintained by an\n'
+      'automated system based on what\'s in DEPS and your changes will be\n'
+      'overwritten.\n'
+      'See https://sites.google.com/a/chromium.org/dev/developers/how-tos/get-the-code#Rolling_DEPS\n'
+      'for more information')]
+  return []
+
+
+def _CheckValidHostsInDEPS(input_api, output_api):
+  """Checks that DEPS file deps are from allowed_hosts."""
+  # Run only if DEPS file has been modified to annoy fewer bystanders.
+  if all(f.LocalPath() != 'DEPS' for f in input_api.AffectedFiles()):
+    return []
+  # Outsource work to gclient verify
+  try:
+    input_api.subprocess.check_output(['gclient', 'verify'])
+    return []
+  except input_api.subprocess.CalledProcessError, error:
+    return [output_api.PresubmitError(
+        'DEPS file must have only git dependencies.',
+        long_text=error.output)]
+
+
+def _CheckNoBannedFunctions(input_api, output_api):
+  """Make sure that banned functions are not used."""
+  warnings = []
+  errors = []
+
+  file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
+  for f in input_api.AffectedFiles(file_filter=file_filter):
+    for line_num, line in f.ChangedContents():
+      for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
+        matched = False
+        if func_name[0:1] == '/':
+          regex = func_name[1:]
+          if input_api.re.search(regex, line):
+            matched = True
+        elif func_name in line:
+            matched = True
+        if matched:
+          problems = warnings;
+          if error:
+            problems = errors;
+          problems.append('    %s:%d:' % (f.LocalPath(), line_num))
+          for message_line in message:
+            problems.append('      %s' % message_line)
+
+  file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
+  for f in input_api.AffectedFiles(file_filter=file_filter):
+    for line_num, line in f.ChangedContents():
+      for func_name, message, error, excluded_paths in _BANNED_CPP_FUNCTIONS:
+        def IsBlacklisted(affected_file, blacklist):
+          local_path = affected_file.LocalPath()
+          for item in blacklist:
+            if input_api.re.match(item, local_path):
+              return True
+          return False
+        if IsBlacklisted(f, excluded_paths):
+          continue
+        matched = False
+        if func_name[0:1] == '/':
+          regex = func_name[1:]
+          if input_api.re.search(regex, line):
+            matched = True
+        elif func_name in line:
+            matched = True
+        if matched:
+          problems = warnings;
+          if error:
+            problems = errors;
+          problems.append('    %s:%d:' % (f.LocalPath(), line_num))
+          for message_line in message:
+            problems.append('      %s' % message_line)
+
+  result = []
+  if (warnings):
+    result.append(output_api.PresubmitPromptWarning(
+        'Banned functions were used.\n' + '\n'.join(warnings)))
+  if (errors):
+    result.append(output_api.PresubmitError(
+        'Banned functions were used.\n' + '\n'.join(errors)))
+  return result
+
+
+def _CheckNoPragmaOnce(input_api, output_api):
+  """Make sure that banned functions are not used."""
+  files = []
+  pattern = input_api.re.compile(r'^#pragma\s+once',
+                                 input_api.re.MULTILINE)
+  for f in input_api.AffectedSourceFiles(input_api.FilterSourceFile):
+    if not f.LocalPath().endswith('.h'):
+      continue
+    contents = input_api.ReadFile(f)
+    if pattern.search(contents):
+      files.append(f)
+
+  if files:
+    return [output_api.PresubmitError(
+        'Do not use #pragma once in header files.\n'
+        'See http://www.chromium.org/developers/coding-style#TOC-File-headers',
+        files)]
+  return []
+
+
+def _CheckNoTrinaryTrueFalse(input_api, output_api):
+  """Checks to make sure we don't introduce use of foo ? true : false."""
+  problems = []
+  pattern = input_api.re.compile(r'\?\s*(true|false)\s*:\s*(true|false)')
+  for f in input_api.AffectedFiles():
+    if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
+      continue
+
+    for line_num, line in f.ChangedContents():
+      if pattern.match(line):
+        problems.append('    %s:%d' % (f.LocalPath(), line_num))
+
+  if not problems:
+    return []
+  return [output_api.PresubmitPromptWarning(
+      'Please consider avoiding the "? true : false" pattern if possible.\n' +
+      '\n'.join(problems))]
+
+
+def _CheckUnwantedDependencies(input_api, output_api):
+  """Runs checkdeps on #include statements added in this
+  change. Breaking - rules is an error, breaking ! rules is a
+  warning.
+  """
+  import sys
+  # We need to wait until we have an input_api object and use this
+  # roundabout construct to import checkdeps because this file is
+  # eval-ed and thus doesn't have __file__.
+  original_sys_path = sys.path
+  try:
+    sys.path = sys.path + [input_api.os_path.join(
+        input_api.PresubmitLocalPath(), 'buildtools', 'checkdeps')]
+    import checkdeps
+    from cpp_checker import CppChecker
+    from rules import Rule
+  finally:
+    # Restore sys.path to what it was before.
+    sys.path = original_sys_path
+
+  added_includes = []
+  for f in input_api.AffectedFiles():
+    if not CppChecker.IsCppFile(f.LocalPath()):
+      continue
+
+    changed_lines = [line for line_num, line in f.ChangedContents()]
+    added_includes.append([f.LocalPath(), changed_lines])
+
+  deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())
+
+  error_descriptions = []
+  warning_descriptions = []
+  for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
+      added_includes):
+    description_with_path = '%s\n    %s' % (path, rule_description)
+    if rule_type == Rule.DISALLOW:
+      error_descriptions.append(description_with_path)
+    else:
+      warning_descriptions.append(description_with_path)
+
+  results = []
+  if error_descriptions:
+    results.append(output_api.PresubmitError(
+        'You added one or more #includes that violate checkdeps rules.',
+        error_descriptions))
+  if warning_descriptions:
+    results.append(output_api.PresubmitPromptOrNotify(
+        'You added one or more #includes of files that are temporarily\n'
+        'allowed but being removed. Can you avoid introducing the\n'
+        '#include? See relevant DEPS file(s) for details and contacts.',
+        warning_descriptions))
+  return results
+
+
+def _CheckFilePermissions(input_api, output_api):
+  """Check that all files have their permissions properly set."""
+  if input_api.platform == 'win32':
+    return []
+  args = [input_api.python_executable, 'tools/checkperms/checkperms.py',
+          '--root', input_api.change.RepositoryRoot()]
+  for f in input_api.AffectedFiles():
+    args += ['--file', f.LocalPath()]
+  checkperms = input_api.subprocess.Popen(args,
+                                          stdout=input_api.subprocess.PIPE)
+  errors = checkperms.communicate()[0].strip()
+  if errors:
+    return [output_api.PresubmitError('checkperms.py failed.',
+                                      errors.splitlines())]
+  return []
+
+
+def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
+  """Makes sure we don't include ui/aura/window_property.h
+  in header files.
+  """
+  pattern = input_api.re.compile(r'^#include\s*"ui/aura/window_property.h"')
+  errors = []
+  for f in input_api.AffectedFiles():
+    if not f.LocalPath().endswith('.h'):
+      continue
+    for line_num, line in f.ChangedContents():
+      if pattern.match(line):
+        errors.append('    %s:%d' % (f.LocalPath(), line_num))
+
+  results = []
+  if errors:
+    results.append(output_api.PresubmitError(
+      'Header files should not include ui/aura/window_property.h', errors))
+  return results
+
+
+def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
+  """Checks that the lines in scope occur in the right order.
+
+  1. C system files in alphabetical order
+  2. C++ system files in alphabetical order
+  3. Project's .h files
+  """
+
+  c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
+  cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
+  custom_include_pattern = input_api.re.compile(r'\s*#include ".*')
+
+  C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3)
+
+  state = C_SYSTEM_INCLUDES
+
+  previous_line = ''
+  previous_line_num = 0
+  problem_linenums = []
+  out_of_order = " - line belongs before previous line"
+  for line_num, line in scope:
+    if c_system_include_pattern.match(line):
+      if state != C_SYSTEM_INCLUDES:
+        problem_linenums.append((line_num, previous_line_num,
+            " - C system include file in wrong block"))
+      elif previous_line and previous_line > line:
+        problem_linenums.append((line_num, previous_line_num,
+            out_of_order))
+    elif cpp_system_include_pattern.match(line):
+      if state == C_SYSTEM_INCLUDES:
+        state = CPP_SYSTEM_INCLUDES
+      elif state == CUSTOM_INCLUDES:
+        problem_linenums.append((line_num, previous_line_num,
+            " - c++ system include file in wrong block"))
+      elif previous_line and previous_line > line:
+        problem_linenums.append((line_num, previous_line_num, out_of_order))
+    elif custom_include_pattern.match(line):
+      if state != CUSTOM_INCLUDES:
+        state = CUSTOM_INCLUDES
+      elif previous_line and previous_line > line:
+        problem_linenums.append((line_num, previous_line_num, out_of_order))
+    else:
+      problem_linenums.append((line_num, previous_line_num,
+          "Unknown include type"))
+    previous_line = line
+    previous_line_num = line_num
+
+  warnings = []
+  for (line_num, previous_line_num, failure_type) in problem_linenums:
+    if line_num in changed_linenums or previous_line_num in changed_linenums:
+      warnings.append('    %s:%d:%s' % (file_path, line_num, failure_type))
+  return warnings
+
+
+def _CheckIncludeOrderInFile(input_api, f, changed_linenums):
+  """Checks the #include order for the given file f."""
+
+  system_include_pattern = input_api.re.compile(r'\s*#include \<.*')
+  # Exclude the following includes from the check:
+  # 1) #include <.../...>, e.g., <sys/...> includes often need to appear in a
+  # specific order.
+  # 2) <atlbase.h>, "build/build_config.h"
+  excluded_include_pattern = input_api.re.compile(
+      r'\s*#include (\<.*/.*|\<atlbase\.h\>|"build/build_config.h")')
+  custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"')
+  # Match the final or penultimate token if it is xxxtest so we can ignore it
+  # when considering the special first include.
+  test_file_tag_pattern = input_api.re.compile(
+    r'_[a-z]+test(?=(_[a-zA-Z0-9]+)?\.)')
+  if_pattern = input_api.re.compile(
+      r'\s*#\s*(if|elif|else|endif|define|undef).*')
+  # Some files need specialized order of includes; exclude such files from this
+  # check.
+  uncheckable_includes_pattern = input_api.re.compile(
+      r'\s*#include '
+      '("ipc/.*macros\.h"|<windows\.h>|".*gl.*autogen.h")\s*')
+
+  contents = f.NewContents()
+  warnings = []
+  line_num = 0
+
+  # Handle the special first include. If the first include file is
+  # some/path/file.h, the corresponding including file can be some/path/file.cc,
+  # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h
+  # etc. It's also possible that no special first include exists.
+  # If the included file is some/path/file_platform.h the including file could
+  # also be some/path/file_xxxtest_platform.h.
+  including_file_base_name = test_file_tag_pattern.sub(
+    '', input_api.os_path.basename(f.LocalPath()))
+
+  for line in contents:
+    line_num += 1
+    if system_include_pattern.match(line):
+      # No special first include -> process the line again along with normal
+      # includes.
+      line_num -= 1
+      break
+    match = custom_include_pattern.match(line)
+    if match:
+      match_dict = match.groupdict()
+      header_basename = test_file_tag_pattern.sub(
+        '', input_api.os_path.basename(match_dict['FILE'])).replace('.h', '')
+
+      if header_basename not in including_file_base_name:
+        # No special first include -> process the line again along with normal
+        # includes.
+        line_num -= 1
+      break
+
+  # Split into scopes: Each region between #if and #endif is its own scope.
+  scopes = []
+  current_scope = []
+  for line in contents[line_num:]:
+    line_num += 1
+    if uncheckable_includes_pattern.match(line):
+      continue
+    if if_pattern.match(line):
+      scopes.append(current_scope)
+      current_scope = []
+    elif ((system_include_pattern.match(line) or
+           custom_include_pattern.match(line)) and
+          not excluded_include_pattern.match(line)):
+      current_scope.append((line_num, line))
+  scopes.append(current_scope)
+
+  for scope in scopes:
+    warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
+                                               changed_linenums))
+  return warnings
+
+
+def _CheckIncludeOrder(input_api, output_api):
+  """Checks that the #include order is correct.
+
+  1. The corresponding header for source files.
+  2. C system files in alphabetical order
+  3. C++ system files in alphabetical order
+  4. Project's .h files in alphabetical order
+
+  Each region separated by #if, #elif, #else, #endif, #define and #undef follows
+  these rules separately.
+  """
+  def FileFilterIncludeOrder(affected_file):
+    black_list = (_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
+    return input_api.FilterSourceFile(affected_file, black_list=black_list)
+
+  warnings = []
+  for f in input_api.AffectedFiles(file_filter=FileFilterIncludeOrder):
+    if f.LocalPath().endswith(('.cc', '.h', '.mm')):
+      changed_linenums = set(line_num for line_num, _ in f.ChangedContents())
+      warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums))
+
+  results = []
+  if warnings:
+    results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_ORDER_WARNING,
+                                                      warnings))
+  return results
+
+
+def _CheckForVersionControlConflictsInFile(input_api, f):
+  pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$')
+  errors = []
+  for line_num, line in f.ChangedContents():
+    if f.LocalPath().endswith('.md'):
+      # First-level headers in markdown look a lot like version control
+      # conflict markers. http://daringfireball.net/projects/markdown/basics
+      continue
+    if pattern.match(line):
+      errors.append('    %s:%d %s' % (f.LocalPath(), line_num, line))
+  return errors
+
+
+def _CheckForVersionControlConflicts(input_api, output_api):
+  """Usually this is not intentional and will cause a compile failure."""
+  errors = []
+  for f in input_api.AffectedFiles():
+    errors.extend(_CheckForVersionControlConflictsInFile(input_api, f))
+
+  results = []
+  if errors:
+    results.append(output_api.PresubmitError(
+      'Version control conflict markers found, please resolve.', errors))
+  return results
+
+
+def _CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api):
+  def FilterFile(affected_file):
+    """Filter function for use with input_api.AffectedSourceFiles,
+    below.  This filters out everything except non-test files from
+    top-level directories that generally speaking should not hard-code
+    service URLs (e.g. src/android_webview/, src/content/ and others).
+    """
+    return input_api.FilterSourceFile(
+      affected_file,
+      white_list=(r'^(android_webview|base|content|net)[\\\/].*', ),
+      black_list=(_EXCLUDED_PATHS +
+                  _TEST_CODE_EXCLUDED_PATHS +
+                  input_api.DEFAULT_BLACK_LIST))
+
+  base_pattern = '"[^"]*google\.com[^"]*"'
+  comment_pattern = input_api.re.compile('//.*%s' % base_pattern)
+  pattern = input_api.re.compile(base_pattern)
+  problems = []  # items are (filename, line_number, line)
+  for f in input_api.AffectedSourceFiles(FilterFile):
+    for line_num, line in f.ChangedContents():
+      if not comment_pattern.search(line) and pattern.search(line):
+        problems.append((f.LocalPath(), line_num, line))
+
+  if problems:
+    return [output_api.PresubmitPromptOrNotify(
+        'Most layers below src/chrome/ should not hardcode service URLs.\n'
+        'Are you sure this is correct?',
+        ['  %s:%d:  %s' % (
+            problem[0], problem[1], problem[2]) for problem in problems])]
+  else:
+    return []
+
+
+def _CheckNoAbbreviationInPngFileName(input_api, output_api):
+  """Makes sure there are no abbreviations in the name of PNG files.
+  The native_client_sdk directory is excluded because it has auto-generated PNG
+  files for documentation.
+  """
+  errors = []
+  white_list = (r'.*_[a-z]_.*\.png$|.*_[a-z]\.png$',)
+  black_list = (r'^native_client_sdk[\\\/]',)
+  file_filter = lambda f: input_api.FilterSourceFile(
+      f, white_list=white_list, black_list=black_list)
+  for f in input_api.AffectedFiles(include_deletes=False,
+                                   file_filter=file_filter):
+    errors.append('    %s' % f.LocalPath())
+
+  results = []
+  if errors:
+    results.append(output_api.PresubmitError(
+        'The name of PNG files should not have abbreviations. \n'
+        'Use _hover.png, _center.png, instead of _h.png, _c.png.\n'
+        'Contact oshima@chromium.org if you have questions.', errors))
+  return results
+
+
+def _FilesToCheckForIncomingDeps(re, changed_lines):
+  """Helper method for _CheckAddedDepsHaveTargetApprovals. Returns
+  a set of DEPS entries that we should look up.
+
+  For a directory (rather than a specific filename) we fake a path to
+  a specific filename by adding /DEPS. This is chosen as a file that
+  will seldom or never be subject to per-file include_rules.
+  """
+  # We ignore deps entries on auto-generated directories.
+  AUTO_GENERATED_DIRS = ['grit', 'jni']
+
+  # This pattern grabs the path without basename in the first
+  # parentheses, and the basename (if present) in the second. It
+  # relies on the simple heuristic that if there is a basename it will
+  # be a header file ending in ".h".
+  pattern = re.compile(
+      r"""['"]\+([^'"]+?)(/[a-zA-Z0-9_]+\.h)?['"].*""")
+  results = set()
+  for changed_line in changed_lines:
+    m = pattern.match(changed_line)
+    if m:
+      path = m.group(1)
+      if path.split('/')[0] not in AUTO_GENERATED_DIRS:
+        if m.group(2):
+          results.add('%s%s' % (path, m.group(2)))
+        else:
+          results.add('%s/DEPS' % path)
+  return results
+
+
+def _CheckAddedDepsHaveTargetApprovals(input_api, output_api):
+  """When a dependency prefixed with + is added to a DEPS file, we
+  want to make sure that the change is reviewed by an OWNER of the
+  target file or directory, to avoid layering violations from being
+  introduced. This check verifies that this happens.
+  """
+  changed_lines = set()
+  for f in input_api.AffectedFiles():
+    filename = input_api.os_path.basename(f.LocalPath())
+    if filename == 'DEPS':
+      changed_lines |= set(line.strip()
+                           for line_num, line
+                           in f.ChangedContents())
+  if not changed_lines:
+    return []
+
+  virtual_depended_on_files = _FilesToCheckForIncomingDeps(input_api.re,
+                                                           changed_lines)
+  if not virtual_depended_on_files:
+    return []
+
+  if input_api.is_committing:
+    if input_api.tbr:
+      return [output_api.PresubmitNotifyResult(
+          '--tbr was specified, skipping OWNERS check for DEPS additions')]
+    if not input_api.change.issue:
+      return [output_api.PresubmitError(
+          "DEPS approval by OWNERS check failed: this change has "
+          "no Rietveld issue number, so we can't check it for approvals.")]
+    output = output_api.PresubmitError
+  else:
+    output = output_api.PresubmitNotifyResult
+
+  owners_db = input_api.owners_db
+  owner_email, reviewers = input_api.canned_checks._RietveldOwnerAndReviewers(
+      input_api,
+      owners_db.email_regexp,
+      approval_needed=input_api.is_committing)
+
+  owner_email = owner_email or input_api.change.author_email
+
+  reviewers_plus_owner = set(reviewers)
+  if owner_email:
+    reviewers_plus_owner.add(owner_email)
+  missing_files = owners_db.files_not_covered_by(virtual_depended_on_files,
+                                                 reviewers_plus_owner)
+
+  # We strip the /DEPS part that was added by
+  # _FilesToCheckForIncomingDeps to fake a path to a file in a
+  # directory.
+  def StripDeps(path):
+    start_deps = path.rfind('/DEPS')
+    if start_deps != -1:
+      return path[:start_deps]
+    else:
+      return path
+  unapproved_dependencies = ["'+%s'," % StripDeps(path)
+                             for path in missing_files]
+
+  if unapproved_dependencies:
+    output_list = [
+      output('Missing LGTM from OWNERS of dependencies added to DEPS:\n    %s' %
+             '\n    '.join(sorted(unapproved_dependencies)))]
+    if not input_api.is_committing:
+      suggested_owners = owners_db.reviewers_for(missing_files, owner_email)
+      output_list.append(output(
+          'Suggested missing target path OWNERS:\n    %s' %
+          '\n    '.join(suggested_owners or [])))
+    return output_list
+
+  return []
+
+
+def _CheckSpamLogging(input_api, output_api):
+  file_inclusion_pattern = r'.+%s' % _IMPLEMENTATION_EXTENSIONS
+  black_list = (_EXCLUDED_PATHS +
+                _TEST_CODE_EXCLUDED_PATHS +
+                input_api.DEFAULT_BLACK_LIST +
+                (r"^base[\\\/]logging\.h$",
+                 r"^base[\\\/]logging\.cc$",
+                 r"^chrome[\\\/]app[\\\/]chrome_main_delegate\.cc$",
+                 r"^chrome[\\\/]browser[\\\/]chrome_browser_main\.cc$",
+                 r"^chrome[\\\/]browser[\\\/]ui[\\\/]startup[\\\/]"
+                     r"startup_browser_creator\.cc$",
+                 r"^chrome[\\\/]installer[\\\/]setup[\\\/].*",
+                 r"chrome[\\\/]browser[\\\/]diagnostics[\\\/]" +
+                     r"diagnostics_writer\.cc$",
+                 r"^chrome_elf[\\\/]dll_hash[\\\/]dll_hash_main\.cc$",
+                 r"^chromecast[\\\/]",
+                 r"^cloud_print[\\\/]",
+                 r"^components[\\\/]html_viewer[\\\/]"
+                     r"web_test_delegate_impl\.cc$",
+                 r"^content[\\\/]common[\\\/]gpu[\\\/]client[\\\/]"
+                     r"gl_helper_benchmark\.cc$",
+                 r"^courgette[\\\/]courgette_tool\.cc$",
+                 r"^extensions[\\\/]renderer[\\\/]logging_native_handler\.cc$",
+                 r"^ipc[\\\/]ipc_logging\.cc$",
+                 r"^native_client_sdk[\\\/]",
+                 r"^remoting[\\\/]base[\\\/]logging\.h$",
+                 r"^remoting[\\\/]host[\\\/].*",
+                 r"^sandbox[\\\/]linux[\\\/].*",
+                 r"^tools[\\\/]",
+                 r"^ui[\\\/]aura[\\\/]bench[\\\/]bench_main\.cc$",
+                 r"^storage[\\\/]browser[\\\/]fileapi[\\\/]" +
+                     r"dump_file_system.cc$",))
+  source_file_filter = lambda x: input_api.FilterSourceFile(
+      x, white_list=(file_inclusion_pattern,), black_list=black_list)
+
+  log_info = []
+  printf = []
+
+  for f in input_api.AffectedSourceFiles(source_file_filter):
+    contents = input_api.ReadFile(f, 'rb')
+    if input_api.re.search(r"\bD?LOG\s*\(\s*INFO\s*\)", contents):
+      log_info.append(f.LocalPath())
+    elif input_api.re.search(r"\bD?LOG_IF\s*\(\s*INFO\s*,", contents):
+      log_info.append(f.LocalPath())
+
+    if input_api.re.search(r"\bprintf\(", contents):
+      printf.append(f.LocalPath())
+    elif input_api.re.search(r"\bfprintf\((stdout|stderr)", contents):
+      printf.append(f.LocalPath())
+
+  if log_info:
+    return [output_api.PresubmitError(
+      'These files spam the console log with LOG(INFO):',
+      items=log_info)]
+  if printf:
+    return [output_api.PresubmitError(
+      'These files spam the console log with printf/fprintf:',
+      items=printf)]
+  return []
+
+
+def _CheckForAnonymousVariables(input_api, output_api):
+  """These types are all expected to hold locks while in scope and
+     so should never be anonymous (which causes them to be immediately
+     destroyed)."""
+  they_who_must_be_named = [
+    'base::AutoLock',
+    'base::AutoReset',
+    'base::AutoUnlock',
+    'SkAutoAlphaRestore',
+    'SkAutoBitmapShaderInstall',
+    'SkAutoBlitterChoose',
+    'SkAutoBounderCommit',
+    'SkAutoCallProc',
+    'SkAutoCanvasRestore',
+    'SkAutoCommentBlock',
+    'SkAutoDescriptor',
+    'SkAutoDisableDirectionCheck',
+    'SkAutoDisableOvalCheck',
+    'SkAutoFree',
+    'SkAutoGlyphCache',
+    'SkAutoHDC',
+    'SkAutoLockColors',
+    'SkAutoLockPixels',
+    'SkAutoMalloc',
+    'SkAutoMaskFreeImage',
+    'SkAutoMutexAcquire',
+    'SkAutoPathBoundsUpdate',
+    'SkAutoPDFRelease',
+    'SkAutoRasterClipValidate',
+    'SkAutoRef',
+    'SkAutoTime',
+    'SkAutoTrace',
+    'SkAutoUnref',
+  ]
+  anonymous = r'(%s)\s*[({]' % '|'.join(they_who_must_be_named)
+  # bad: base::AutoLock(lock.get());
+  # not bad: base::AutoLock lock(lock.get());
+  bad_pattern = input_api.re.compile(anonymous)
+  # good: new base::AutoLock(lock.get())
+  good_pattern = input_api.re.compile(r'\bnew\s*' + anonymous)
+  errors = []
+
+  for f in input_api.AffectedFiles():
+    if not f.LocalPath().endswith(('.cc', '.h', '.inl', '.m', '.mm')):
+      continue
+    for linenum, line in f.ChangedContents():
+      if bad_pattern.search(line) and not good_pattern.search(line):
+        errors.append('%s:%d' % (f.LocalPath(), linenum))
+
+  if errors:
+    return [output_api.PresubmitError(
+      'These lines create anonymous variables that need to be named:',
+      items=errors)]
+  return []
+
+
+def _CheckCygwinShell(input_api, output_api):
+  source_file_filter = lambda x: input_api.FilterSourceFile(
+      x, white_list=(r'.+\.(gyp|gypi)$',))
+  cygwin_shell = []
+
+  for f in input_api.AffectedSourceFiles(source_file_filter):
+    for linenum, line in f.ChangedContents():
+      if 'msvs_cygwin_shell' in line:
+        cygwin_shell.append(f.LocalPath())
+        break
+
+  if cygwin_shell:
+    return [output_api.PresubmitError(
+      'These files should not use msvs_cygwin_shell (the default is 0):',
+      items=cygwin_shell)]
+  return []
+
+
+def _CheckUserActionUpdate(input_api, output_api):
+  """Checks if any new user action has been added."""
+  if any('actions.xml' == input_api.os_path.basename(f) for f in
+         input_api.LocalPaths()):
+    # If actions.xml is already included in the changelist, the PRESUBMIT
+    # for actions.xml will do a more complete presubmit check.
+    return []
+
+  file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm'))
+  action_re = r'[^a-zA-Z]UserMetricsAction\("([^"]*)'
+  current_actions = None
+  for f in input_api.AffectedFiles(file_filter=file_filter):
+    for line_num, line in f.ChangedContents():
+      match = input_api.re.search(action_re, line)
+      if match:
+        # Loads contents in tools/metrics/actions/actions.xml to memory. It's
+        # loaded only once.
+        if not current_actions:
+          with open('tools/metrics/actions/actions.xml') as actions_f:
+            current_actions = actions_f.read()
+        # Search for the matched user action name in |current_actions|.
+        for action_name in match.groups():
+          action = 'name="{0}"'.format(action_name)
+          if action not in current_actions:
+            return [output_api.PresubmitPromptWarning(
+              'File %s line %d: %s is missing in '
+              'tools/metrics/actions/actions.xml. Please run '
+              'tools/metrics/actions/extract_actions.py to update.'
+              % (f.LocalPath(), line_num, action_name))]
+  return []
+
+
+def _GetJSONParseError(input_api, filename, eat_comments=True):
+  try:
+    contents = input_api.ReadFile(filename)
+    if eat_comments:
+      import sys
+      original_sys_path = sys.path
+      try:
+        sys.path = sys.path + [input_api.os_path.join(
+            input_api.PresubmitLocalPath(),
+            'tools', 'json_comment_eater')]
+        import json_comment_eater
+      finally:
+        sys.path = original_sys_path
+      contents = json_comment_eater.Nom(contents)
+
+    input_api.json.loads(contents)
+  except ValueError as e:
+    return e
+  return None
+
+
+def _GetIDLParseError(input_api, filename):
+  try:
+    contents = input_api.ReadFile(filename)
+    idl_schema = input_api.os_path.join(
+        input_api.PresubmitLocalPath(),
+        'tools', 'json_schema_compiler', 'idl_schema.py')
+    process = input_api.subprocess.Popen(
+        [input_api.python_executable, idl_schema],
+        stdin=input_api.subprocess.PIPE,
+        stdout=input_api.subprocess.PIPE,
+        stderr=input_api.subprocess.PIPE,
+        universal_newlines=True)
+    (_, error) = process.communicate(input=contents)
+    return error or None
+  except ValueError as e:
+    return e
+
+
+def _CheckParseErrors(input_api, output_api):
+  """Check that IDL and JSON files do not contain syntax errors."""
+  actions = {
+    '.idl': _GetIDLParseError,
+    '.json': _GetJSONParseError,
+  }
+  # These paths contain test data and other known invalid JSON files.
+  excluded_patterns = [
+    r'test[\\\/]data[\\\/]',
+    r'^components[\\\/]policy[\\\/]resources[\\\/]policy_templates\.json$',
+  ]
+  # Most JSON files are preprocessed and support comments, but these do not.
+  json_no_comments_patterns = [
+    r'^testing[\\\/]',
+  ]
+  # Only run IDL checker on files in these directories.
+  idl_included_patterns = [
+    r'^chrome[\\\/]common[\\\/]extensions[\\\/]api[\\\/]',
+    r'^extensions[\\\/]common[\\\/]api[\\\/]',
+  ]
+
+  def get_action(affected_file):
+    filename = affected_file.LocalPath()
+    return actions.get(input_api.os_path.splitext(filename)[1])
+
+  def MatchesFile(patterns, path):
+    for pattern in patterns:
+      if input_api.re.search(pattern, path):
+        return True
+    return False
+
+  def FilterFile(affected_file):
+    action = get_action(affected_file)
+    if not action:
+      return False
+    path = affected_file.LocalPath()
+
+    if MatchesFile(excluded_patterns, path):
+      return False
+
+    if (action == _GetIDLParseError and
+        not MatchesFile(idl_included_patterns, path)):
+      return False
+    return True
+
+  results = []
+  for affected_file in input_api.AffectedFiles(
+      file_filter=FilterFile, include_deletes=False):
+    action = get_action(affected_file)
+    kwargs = {}
+    if (action == _GetJSONParseError and
+        MatchesFile(json_no_comments_patterns, affected_file.LocalPath())):
+      kwargs['eat_comments'] = False
+    parse_error = action(input_api,
+                         affected_file.AbsoluteLocalPath(),
+                         **kwargs)
+    if parse_error:
+      results.append(output_api.PresubmitError('%s could not be parsed: %s' %
+          (affected_file.LocalPath(), parse_error)))
+  return results
+
+
+def _CheckJavaStyle(input_api, output_api):
+  """Runs checkstyle on changed java files and returns errors if any exist."""
+  import sys
+  original_sys_path = sys.path
+  try:
+    sys.path = sys.path + [input_api.os_path.join(
+        input_api.PresubmitLocalPath(), 'tools', 'android', 'checkstyle')]
+    import checkstyle
+  finally:
+    # Restore sys.path to what it was before.
+    sys.path = original_sys_path
+
+  return checkstyle.RunCheckstyle(
+      input_api, output_api, 'tools/android/checkstyle/chromium-style-5.0.xml',
+      black_list=_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
+
+
+def _CheckAndroidToastUsage(input_api, output_api):
+  """Checks that code uses org.chromium.ui.widget.Toast instead of
+     android.widget.Toast (Chromium Toast doesn't force hardware
+     acceleration on low-end devices, saving memory).
+  """
+  toast_import_pattern = input_api.re.compile(
+      r'^import android\.widget\.Toast;$')
+
+  errors = []
+
+  sources = lambda affected_file: input_api.FilterSourceFile(
+      affected_file,
+      black_list=(_EXCLUDED_PATHS +
+                  _TEST_CODE_EXCLUDED_PATHS +
+                  input_api.DEFAULT_BLACK_LIST +
+                  (r'^chromecast[\\\/].*',
+                   r'^remoting[\\\/].*')),
+      white_list=(r'.*\.java$',))
+
+  for f in input_api.AffectedSourceFiles(sources):
+    for line_num, line in f.ChangedContents():
+      if toast_import_pattern.search(line):
+        errors.append("%s:%d" % (f.LocalPath(), line_num))
+
+  results = []
+
+  if errors:
+    results.append(output_api.PresubmitError(
+        'android.widget.Toast usage is detected. Android toasts use hardware'
+        ' acceleration, and can be\ncostly on low-end devices. Please use'
+        ' org.chromium.ui.widget.Toast instead.\n'
+        'Contact dskiba@chromium.org if you have any questions.',
+        errors))
+
+  return results
+
+
+def _CheckAndroidCrLogUsage(input_api, output_api):
+  """Checks that new logs using org.chromium.base.Log:
+    - Are using 'TAG' as variable name for the tags (warn)
+    - Are using a tag that is shorter than 20 characters (error)
+  """
+  cr_log_import_pattern = input_api.re.compile(
+      r'^import org\.chromium\.base\.Log;$', input_api.re.MULTILINE)
+  class_in_base_pattern = input_api.re.compile(
+      r'^package org\.chromium\.base;$', input_api.re.MULTILINE)
+  has_some_log_import_pattern = input_api.re.compile(
+      r'^import .*\.Log;$', input_api.re.MULTILINE)
+  # Extract the tag from lines like `Log.d(TAG, "*");` or `Log.d("TAG", "*");`
+  log_call_pattern = input_api.re.compile(r'^\s*Log\.\w\((?P<tag>\"?\w+\"?)\,')
+  log_decl_pattern = input_api.re.compile(
+      r'^\s*private static final String TAG = "(?P<name>(.*))";',
+      input_api.re.MULTILINE)
+
+  REF_MSG = ('See docs/android_logging.md '
+            'or contact dgn@chromium.org for more info.')
+  sources = lambda x: input_api.FilterSourceFile(x, white_list=(r'.*\.java$',))
+
+  tag_decl_errors = []
+  tag_length_errors = []
+  tag_errors = []
+  tag_with_dot_errors = []
+  util_log_errors = []
+
+  for f in input_api.AffectedSourceFiles(sources):
+    file_content = input_api.ReadFile(f)
+    has_modified_logs = False
+
+    # Per line checks
+    if (cr_log_import_pattern.search(file_content) or
+        (class_in_base_pattern.search(file_content) and
+            not has_some_log_import_pattern.search(file_content))):
+      # Checks to run for files using cr log
+      for line_num, line in f.ChangedContents():
+
+        # Check if the new line is doing some logging
+        match = log_call_pattern.search(line)
+        if match:
+          has_modified_logs = True
+
+          # Make sure it uses "TAG"
+          if not match.group('tag') == 'TAG':
+            tag_errors.append("%s:%d" % (f.LocalPath(), line_num))
+    else:
+      # Report non cr Log function calls in changed lines
+      for line_num, line in f.ChangedContents():
+        if log_call_pattern.search(line):
+          util_log_errors.append("%s:%d" % (f.LocalPath(), line_num))
+
+    # Per file checks
+    if has_modified_logs:
+      # Make sure the tag is using the "cr" prefix and is not too long
+      match = log_decl_pattern.search(file_content)
+      tag_name = match.group('name') if match else None
+      if not tag_name:
+        tag_decl_errors.append(f.LocalPath())
+      elif len(tag_name) > 20:
+        tag_length_errors.append(f.LocalPath())
+      elif '.' in tag_name:
+        tag_with_dot_errors.append(f.LocalPath())
+
+  results = []
+  if tag_decl_errors:
+    results.append(output_api.PresubmitPromptWarning(
+        'Please define your tags using the suggested format: .\n'
+        '"private static final String TAG = "<package tag>".\n'
+        'They will be prepended with "cr_" automatically.\n' + REF_MSG,
+        tag_decl_errors))
+
+  if tag_length_errors:
+    results.append(output_api.PresubmitError(
+        'The tag length is restricted by the system to be at most '
+        '20 characters.\n' + REF_MSG,
+        tag_length_errors))
+
+  if tag_errors:
+    results.append(output_api.PresubmitPromptWarning(
+        'Please use a variable named "TAG" for your log tags.\n' + REF_MSG,
+        tag_errors))
+
+  if util_log_errors:
+    results.append(output_api.PresubmitPromptWarning(
+        'Please use org.chromium.base.Log for new logs.\n' + REF_MSG,
+        util_log_errors))
+
+  if tag_with_dot_errors:
+    results.append(output_api.PresubmitPromptWarning(
+        'Dot in log tags cause them to be elided in crash reports.\n' + REF_MSG,
+        tag_with_dot_errors))
+
+  return results
+
+
+def _CheckForCopyrightedCode(input_api, output_api):
+  """Verifies that newly added code doesn't contain copyrighted material
+  and is properly licensed under the standard Chromium license.
+
+  As there can be false positives, we maintain a whitelist file. This check
+  also verifies that the whitelist file is up to date.
+  """
+  import sys
+  original_sys_path = sys.path
+  try:
+    sys.path = sys.path + [input_api.os_path.join(
+        input_api.PresubmitLocalPath(), 'tools')]
+    from copyright_scanner import copyright_scanner
+  finally:
+    # Restore sys.path to what it was before.
+    sys.path = original_sys_path
+
+  return copyright_scanner.ScanAtPresubmit(input_api, output_api)
+
+
+def _CheckSingletonInHeaders(input_api, output_api):
+  """Checks to make sure no header files have |Singleton<|."""
+  def FileFilter(affected_file):
+    # It's ok for base/memory/singleton.h to have |Singleton<|.
+    black_list = (_EXCLUDED_PATHS +
+                  input_api.DEFAULT_BLACK_LIST +
+                  (r"^base[\\\/]memory[\\\/]singleton\.h$",))
+    return input_api.FilterSourceFile(affected_file, black_list=black_list)
+
+  pattern = input_api.re.compile(r'(?<!class\sbase::)Singleton\s*<')
+  files = []
+  for f in input_api.AffectedSourceFiles(FileFilter):
+    if (f.LocalPath().endswith('.h') or f.LocalPath().endswith('.hxx') or
+        f.LocalPath().endswith('.hpp') or f.LocalPath().endswith('.inl')):
+      contents = input_api.ReadFile(f)
+      for line in contents.splitlines(False):
+        if (not input_api.re.match(r'//', line) and # Strip C++ comment.
+            pattern.search(line)):
+          files.append(f)
+          break
+
+  if files:
+    return [ output_api.PresubmitError(
+        'Found base::Singleton<T> in the following header files.\n' +
+        'Please move them to an appropriate source file so that the ' +
+        'template gets instantiated in a single compilation unit.',
+        files) ]
+  return []
+
+
+_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. Our external
+      documentation and iOS CSS for dom distiller
+      (reader mode) are ignored by the hooks as it
+      needs to be consumed by WebKit. """
+  results = []
+  file_inclusion_pattern = (r".+\.css$",)
+  black_list = (_EXCLUDED_PATHS +
+                _TEST_CODE_EXCLUDED_PATHS +
+                input_api.DEFAULT_BLACK_LIST +
+                (r"^chrome/common/extensions/docs",
+                 r"^chrome/docs",
+                 r"^components/dom_distiller/core/css/distilledpage_ios.css",
+                 r"^native_client_sdk"))
+  file_filter = lambda f: input_api.FilterSourceFile(
+      f, white_list=file_inclusion_pattern, black_list=black_list)
+  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 deprecated_value in 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
+
+
+_DEPRECATED_JS = [
+  ( "__lookupGetter__", "Object.getOwnPropertyDescriptor" ),
+  ( "__defineGetter__", "Object.defineProperty" ),
+  ( "__defineSetter__", "Object.defineProperty" ),
+]
+
+def _CheckNoDeprecatedJS(input_api, output_api):
+  """Make sure that we don't use deprecated JS in Chrome code."""
+  results = []
+  file_inclusion_pattern = (r".+\.js$",)  # TODO(dbeam): .html?
+  black_list = (_EXCLUDED_PATHS + _TEST_CODE_EXCLUDED_PATHS +
+                input_api.DEFAULT_BLACK_LIST)
+  file_filter = lambda f: input_api.FilterSourceFile(
+      f, white_list=file_inclusion_pattern, black_list=black_list)
+  for fpath in input_api.AffectedFiles(file_filter=file_filter):
+    for lnum, line in fpath.ChangedContents():
+      for (deprecated, replacement) in _DEPRECATED_JS:
+        if deprecated in line:
+          results.append(output_api.PresubmitError(
+              "%s:%d: Use of deprecated JS %s, use %s instead" %
+              (fpath.LocalPath(), lnum, deprecated, replacement)))
+  return results
+
+
+def _AndroidSpecificOnUploadChecks(input_api, output_api):
+  """Groups checks that target android code."""
+  results = []
+  results.extend(_CheckAndroidCrLogUsage(input_api, output_api))
+  results.extend(_CheckAndroidToastUsage(input_api, output_api))
+  return results
+
+
+def _CommonChecks(input_api, output_api):
+  """Checks common to both upload and commit."""
+  results = []
+  results.extend(input_api.canned_checks.PanProjectChecks(
+      input_api, output_api,
+      excluded_paths=_EXCLUDED_PATHS + _TESTRUNNER_PATHS))
+  results.extend(_CheckAuthorizedAuthor(input_api, output_api))
+  results.extend(
+      _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
+  results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
+  results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
+  results.extend(_CheckNoNewWStrings(input_api, output_api))
+  results.extend(_CheckNoDEPSGIT(input_api, output_api))
+  results.extend(_CheckNoBannedFunctions(input_api, output_api))
+  results.extend(_CheckNoPragmaOnce(input_api, output_api))
+  results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
+  results.extend(_CheckUnwantedDependencies(input_api, output_api))
+  results.extend(_CheckFilePermissions(input_api, output_api))
+  results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
+  results.extend(_CheckIncludeOrder(input_api, output_api))
+  results.extend(_CheckForVersionControlConflicts(input_api, output_api))
+  results.extend(_CheckPatchFiles(input_api, output_api))
+  results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api))
+  results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api))
+  results.extend(_CheckForInvalidOSMacros(input_api, output_api))
+  results.extend(_CheckForInvalidIfDefinedMacros(input_api, output_api))
+  # TODO(danakj): Remove this when base/move.h is removed.
+  results.extend(_CheckForUsingSideEffectsOfPass(input_api, output_api))
+  results.extend(_CheckAddedDepsHaveTargetApprovals(input_api, output_api))
+  results.extend(
+      input_api.canned_checks.CheckChangeHasNoTabs(
+          input_api,
+          output_api,
+          source_file_filter=lambda x: x.LocalPath().endswith('.grd')))
+  results.extend(_CheckSpamLogging(input_api, output_api))
+  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))
+  results.extend(_CheckNoDeprecatedJS(input_api, output_api))
+  results.extend(_CheckParseErrors(input_api, output_api))
+  results.extend(_CheckForIPCRules(input_api, output_api))
+  results.extend(_CheckForCopyrightedCode(input_api, output_api))
+  results.extend(_CheckForWindowsLineEndings(input_api, output_api))
+  results.extend(_CheckSingletonInHeaders(input_api, output_api))
+
+  if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
+    results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
+        input_api, output_api,
+        input_api.PresubmitLocalPath(),
+        whitelist=[r'^PRESUBMIT_test\.py$']))
+  return results
+
+
+def _CheckAuthorizedAuthor(input_api, output_api):
+  """For non-googler/chromites committers, verify the author's email address is
+  in AUTHORS.
+  """
+  # TODO(maruel): Add it to input_api?
+  import fnmatch
+
+  author = input_api.change.author_email
+  if not author:
+    input_api.logging.info('No author, skipping AUTHOR check')
+    return []
+  authors_path = input_api.os_path.join(
+      input_api.PresubmitLocalPath(), 'AUTHORS')
+  valid_authors = (
+      input_api.re.match(r'[^#]+\s+\<(.+?)\>\s*$', line)
+      for line in open(authors_path))
+  valid_authors = [item.group(1).lower() for item in valid_authors if item]
+  if not any(fnmatch.fnmatch(author.lower(), valid) for valid in valid_authors):
+    input_api.logging.info('Valid authors are %s', ', '.join(valid_authors))
+    return [output_api.PresubmitPromptWarning(
+        ('%s is not in AUTHORS file. If you are a new contributor, please visit'
+        '\n'
+        'http://www.chromium.org/developers/contributing-code and read the '
+        '"Legal" section\n'
+        'If you are a chromite, verify the contributor signed the CLA.') %
+        author)]
+  return []
+
+
+def _CheckPatchFiles(input_api, output_api):
+  problems = [f.LocalPath() for f in input_api.AffectedFiles()
+      if f.LocalPath().endswith(('.orig', '.rej'))]
+  if problems:
+    return [output_api.PresubmitError(
+        "Don't commit .rej and .orig files.", problems)]
+  else:
+    return []
+
+
+def _DidYouMeanOSMacro(bad_macro):
+  try:
+    return {'A': 'OS_ANDROID',
+            'B': 'OS_BSD',
+            'C': 'OS_CHROMEOS',
+            'F': 'OS_FREEBSD',
+            'L': 'OS_LINUX',
+            'M': 'OS_MACOSX',
+            'N': 'OS_NACL',
+            'O': 'OS_OPENBSD',
+            'P': 'OS_POSIX',
+            'S': 'OS_SOLARIS',
+            'W': 'OS_WIN'}[bad_macro[3].upper()]
+  except KeyError:
+    return ''
+
+
+def _CheckForInvalidOSMacrosInFile(input_api, f):
+  """Check for sensible looking, totally invalid OS macros."""
+  preprocessor_statement = input_api.re.compile(r'^\s*#')
+  os_macro = input_api.re.compile(r'defined\((OS_[^)]+)\)')
+  results = []
+  for lnum, line in f.ChangedContents():
+    if preprocessor_statement.search(line):
+      for match in os_macro.finditer(line):
+        if not match.group(1) in _VALID_OS_MACROS:
+          good = _DidYouMeanOSMacro(match.group(1))
+          did_you_mean = ' (did you mean %s?)' % good if good else ''
+          results.append('    %s:%d %s%s' % (f.LocalPath(),
+                                             lnum,
+                                             match.group(1),
+                                             did_you_mean))
+  return results
+
+
+def _CheckForInvalidOSMacros(input_api, output_api):
+  """Check all affected files for invalid OS macros."""
+  bad_macros = []
+  for f in input_api.AffectedFiles():
+    if not f.LocalPath().endswith(('.py', '.js', '.html', '.css')):
+      bad_macros.extend(_CheckForInvalidOSMacrosInFile(input_api, f))
+
+  if not bad_macros:
+    return []
+
+  return [output_api.PresubmitError(
+      'Possibly invalid OS macro[s] found. Please fix your code\n'
+      'or add your macro to src/PRESUBMIT.py.', bad_macros)]
+
+
+def _CheckForInvalidIfDefinedMacrosInFile(input_api, f):
+  """Check all affected files for invalid "if defined" macros."""
+  ALWAYS_DEFINED_MACROS = (
+      "TARGET_CPU_PPC",
+      "TARGET_CPU_PPC64",
+      "TARGET_CPU_68K",
+      "TARGET_CPU_X86",
+      "TARGET_CPU_ARM",
+      "TARGET_CPU_MIPS",
+      "TARGET_CPU_SPARC",
+      "TARGET_CPU_ALPHA",
+      "TARGET_IPHONE_SIMULATOR",
+      "TARGET_OS_EMBEDDED",
+      "TARGET_OS_IPHONE",
+      "TARGET_OS_MAC",
+      "TARGET_OS_UNIX",
+      "TARGET_OS_WIN32",
+  )
+  ifdef_macro = input_api.re.compile(r'^\s*#.*(?:ifdef\s|defined\()([^\s\)]+)')
+  results = []
+  for lnum, line in f.ChangedContents():
+    for match in ifdef_macro.finditer(line):
+      if match.group(1) in ALWAYS_DEFINED_MACROS:
+        always_defined = ' %s is always defined. ' % match.group(1)
+        did_you_mean = 'Did you mean \'#if %s\'?' % match.group(1)
+        results.append('    %s:%d %s\n\t%s' % (f.LocalPath(),
+                                               lnum,
+                                               always_defined,
+                                               did_you_mean))
+  return results
+
+
+def _CheckForInvalidIfDefinedMacros(input_api, output_api):
+  """Check all affected files for invalid "if defined" macros."""
+  bad_macros = []
+  for f in input_api.AffectedFiles():
+    if f.LocalPath().endswith(('.h', '.c', '.cc', '.m', '.mm')):
+      bad_macros.extend(_CheckForInvalidIfDefinedMacrosInFile(input_api, f))
+
+  if not bad_macros:
+    return []
+
+  return [output_api.PresubmitError(
+      'Found ifdef check on always-defined macro[s]. Please fix your code\n'
+      'or check the list of ALWAYS_DEFINED_MACROS in src/PRESUBMIT.py.',
+      bad_macros)]
+
+
+def _CheckForUsingSideEffectsOfPass(input_api, output_api):
+  """Check all affected files for using side effects of Pass."""
+  errors = []
+  for f in input_api.AffectedFiles():
+    if f.LocalPath().endswith(('.h', '.c', '.cc', '.m', '.mm')):
+      for lnum, line in f.ChangedContents():
+        # Disallow Foo(*my_scoped_thing.Pass()); See crbug.com/418297.
+        if input_api.re.search(r'\*[a-zA-Z0-9_]+\.Pass\(\)', line):
+          errors.append(output_api.PresubmitError(
+            ('%s:%d uses *foo.Pass() to delete the contents of scoped_ptr. ' +
+             'See crbug.com/418297.') % (f.LocalPath(), lnum)))
+  return errors
+
+
+def _CheckForIPCRules(input_api, output_api):
+  """Check for same IPC rules described in
+  http://www.chromium.org/Home/chromium-security/education/security-tips-for-ipc
+  """
+  base_pattern = r'IPC_ENUM_TRAITS\('
+  inclusion_pattern = input_api.re.compile(r'(%s)' % base_pattern)
+  comment_pattern = input_api.re.compile(r'//.*(%s)' % base_pattern)
+
+  problems = []
+  for f in input_api.AffectedSourceFiles(None):
+    local_path = f.LocalPath()
+    if not local_path.endswith('.h'):
+      continue
+    for line_number, line in f.ChangedContents():
+      if inclusion_pattern.search(line) and not comment_pattern.search(line):
+        problems.append(
+          '%s:%d\n    %s' % (local_path, line_number, line.strip()))
+
+  if problems:
+    return [output_api.PresubmitPromptWarning(
+        _IPC_ENUM_TRAITS_DEPRECATED, problems)]
+  else:
+    return []
+
+
+def _CheckForWindowsLineEndings(input_api, output_api):
+  """Check source code and known ascii text files for Windows style line
+  endings.
+  """
+  known_text_files = r'.*\.(txt|html|htm|mhtml|py|gyp|gypi|gn|isolate)$'
+
+  file_inclusion_pattern = (
+    known_text_files,
+    r'.+%s' % _IMPLEMENTATION_EXTENSIONS
+  )
+
+  filter = lambda f: input_api.FilterSourceFile(
+    f, white_list=file_inclusion_pattern, black_list=None)
+  files = [f.LocalPath() for f in
+           input_api.AffectedSourceFiles(filter)]
+
+  problems = []
+
+  for file in files:
+    fp = open(file, 'r')
+    for line in fp:
+      if line.endswith('\r\n'):
+        problems.append(file)
+        break
+    fp.close()
+
+  if problems:
+    return [output_api.PresubmitPromptWarning('Are you sure that you want '
+        'these files to contain Windows style line endings?\n' +
+        '\n'.join(problems))]
+
+  return []
+
+
+def CheckChangeOnUpload(input_api, output_api):
+  results = []
+  results.extend(_CommonChecks(input_api, output_api))
+  results.extend(_CheckValidHostsInDEPS(input_api, output_api))
+  results.extend(_CheckJavaStyle(input_api, output_api))
+  results.extend(
+      input_api.canned_checks.CheckGNFormatted(input_api, output_api))
+  results.extend(_CheckUmaHistogramChanges(input_api, output_api))
+  results.extend(_AndroidSpecificOnUploadChecks(input_api, output_api))
+  return results
+
+
+def GetTryServerMasterForBot(bot):
+  """Returns the Try Server master for the given bot.
+
+  It tries to guess the master from the bot name, but may still fail
+  and return None.  There is no longer a default master.
+  """
+  # Potentially ambiguous bot names are listed explicitly.
+  master_map = {
+      'chromium_presubmit': 'tryserver.chromium.linux',
+      'blink_presubmit': 'tryserver.chromium.linux',
+      'tools_build_presubmit': 'tryserver.chromium.linux',
+  }
+  master = master_map.get(bot)
+  if not master:
+    if 'linux' in bot or 'android' in bot or 'presubmit' in bot:
+      master = 'tryserver.chromium.linux'
+    elif 'win' in bot:
+      master = 'tryserver.chromium.win'
+    elif 'mac' in bot or 'ios' in bot:
+      master = 'tryserver.chromium.mac'
+  return master
+
+
+def GetDefaultTryConfigs(bots):
+  """Returns a list of ('bot', set(['tests']), filtered by [bots].
+  """
+
+  builders_and_tests = dict((bot, set(['defaulttests'])) for bot in bots)
+
+  # Build up the mapping from tryserver master to bot/test.
+  out = dict()
+  for bot, tests in builders_and_tests.iteritems():
+    out.setdefault(GetTryServerMasterForBot(bot), {})[bot] = tests
+  return out
+
+
+def CheckChangeOnCommit(input_api, output_api):
+  results = []
+  results.extend(_CommonChecks(input_api, output_api))
+  # TODO(thestig) temporarily disabled, doesn't work in third_party/
+  #results.extend(input_api.canned_checks.CheckSvnModifiedDirectories(
+  #    input_api, output_api, sources))
+  # Make sure the tree is 'open'.
+  results.extend(input_api.canned_checks.CheckTreeIsOpen(
+      input_api,
+      output_api,
+      json_url='http://chromium-status.appspot.com/current?format=json'))
+
+  results.extend(input_api.canned_checks.CheckChangeHasBugField(
+      input_api, output_api))
+  results.extend(input_api.canned_checks.CheckChangeHasDescription(
+      input_api, output_api))
+  return results
+
+
+def GetPreferredTryMasters(project, change):
+  import json
+  import os.path
+  import platform
+  import subprocess
+
+  cq_config_path = os.path.join(
+      change.RepositoryRoot(), 'infra', 'config', 'cq.cfg')
+  # commit_queue.py below is a script in depot_tools directory, which has a
+  # 'builders' command to retrieve a list of CQ builders from the CQ config.
+  is_win = platform.system() == 'Windows'
+  masters = json.loads(subprocess.check_output(
+      ['commit_queue', 'builders', cq_config_path], shell=is_win))
+
+  try_config = {}
+  for master in masters:
+    try_config.setdefault(master, {})
+    for builder in masters[master]:
+      # Do not trigger presubmit builders, since they're likely to fail
+      # (e.g. OWNERS checks before finished code review), and we're
+      # running local presubmit anyway.
+      if 'presubmit' not in builder:
+        try_config[master][builder] = ['defaulttests']
+
+  return try_config
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
new file mode 100755
index 0000000..4d40d8f
--- /dev/null
+++ b/PRESUBMIT_test.py
@@ -0,0 +1,949 @@
+#!/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.
+
+import glob
+import json
+import os
+import re
+import subprocess
+import sys
+import unittest
+
+import PRESUBMIT
+from PRESUBMIT_test_mocks import MockChange, MockFile, MockAffectedFile
+from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi
+
+_TEST_DATA_DIR = 'base/test/data/presubmit'
+
+class IncludeOrderTest(unittest.TestCase):
+  def testSystemHeaderOrder(self):
+    scope = [(1, '#include <csystem.h>'),
+             (2, '#include <cppsystem>'),
+             (3, '#include "acustom.h"')]
+    all_linenums = [linenum for (linenum, _) in scope]
+    mock_input_api = MockInputApi()
+    warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
+                                                    '', all_linenums)
+    self.assertEqual(0, len(warnings))
+
+  def testSystemHeaderOrderMismatch1(self):
+    scope = [(10, '#include <cppsystem>'),
+             (20, '#include <csystem.h>'),
+             (30, '#include "acustom.h"')]
+    all_linenums = [linenum for (linenum, _) in scope]
+    mock_input_api = MockInputApi()
+    warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
+                                                    '', all_linenums)
+    self.assertEqual(1, len(warnings))
+    self.assertTrue('20' in warnings[0])
+
+  def testSystemHeaderOrderMismatch2(self):
+    scope = [(10, '#include <cppsystem>'),
+             (20, '#include "acustom.h"'),
+             (30, '#include <csystem.h>')]
+    all_linenums = [linenum for (linenum, _) in scope]
+    mock_input_api = MockInputApi()
+    warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
+                                                    '', all_linenums)
+    self.assertEqual(1, len(warnings))
+    self.assertTrue('30' in warnings[0])
+
+  def testSystemHeaderOrderMismatch3(self):
+    scope = [(10, '#include "acustom.h"'),
+             (20, '#include <csystem.h>'),
+             (30, '#include <cppsystem>')]
+    all_linenums = [linenum for (linenum, _) in scope]
+    mock_input_api = MockInputApi()
+    warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
+                                                    '', all_linenums)
+    self.assertEqual(2, len(warnings))
+    self.assertTrue('20' in warnings[0])
+    self.assertTrue('30' in warnings[1])
+
+  def testAlphabeticalOrderMismatch(self):
+    scope = [(10, '#include <csystem.h>'),
+             (15, '#include <bsystem.h>'),
+             (20, '#include <cppsystem>'),
+             (25, '#include <bppsystem>'),
+             (30, '#include "bcustom.h"'),
+             (35, '#include "acustom.h"')]
+    all_linenums = [linenum for (linenum, _) in scope]
+    mock_input_api = MockInputApi()
+    warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
+                                                    '', all_linenums)
+    self.assertEqual(3, len(warnings))
+    self.assertTrue('15' in warnings[0])
+    self.assertTrue('25' in warnings[1])
+    self.assertTrue('35' in warnings[2])
+
+  def testSpecialFirstInclude1(self):
+    mock_input_api = MockInputApi()
+    contents = ['#include "some/path/foo.h"',
+                '#include "a/header.h"']
+    mock_file = MockFile('some/path/foo.cc', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+  def testSpecialFirstInclude2(self):
+    mock_input_api = MockInputApi()
+    contents = ['#include "some/other/path/foo.h"',
+                '#include "a/header.h"']
+    mock_file = MockFile('some/path/foo.cc', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+  def testSpecialFirstInclude3(self):
+    mock_input_api = MockInputApi()
+    contents = ['#include "some/path/foo.h"',
+                '#include "a/header.h"']
+    mock_file = MockFile('some/path/foo_platform.cc', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+  def testSpecialFirstInclude4(self):
+    mock_input_api = MockInputApi()
+    contents = ['#include "some/path/bar.h"',
+                '#include "a/header.h"']
+    mock_file = MockFile('some/path/foo_platform.cc', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(1, len(warnings))
+    self.assertTrue('2' in warnings[0])
+
+  def testSpecialFirstInclude5(self):
+    mock_input_api = MockInputApi()
+    contents = ['#include "some/other/path/foo.h"',
+                '#include "a/header.h"']
+    mock_file = MockFile('some/path/foo-suffix.h', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+  def testSpecialFirstInclude6(self):
+    mock_input_api = MockInputApi()
+    contents = ['#include "some/other/path/foo_win.h"',
+                '#include <set>',
+                '#include "a/header.h"']
+    mock_file = MockFile('some/path/foo_unittest_win.h', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+  def testOrderAlreadyWrong(self):
+    scope = [(1, '#include "b.h"'),
+             (2, '#include "a.h"'),
+             (3, '#include "c.h"')]
+    mock_input_api = MockInputApi()
+    warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
+                                                    '', [3])
+    self.assertEqual(0, len(warnings))
+
+  def testConflictAdded1(self):
+    scope = [(1, '#include "a.h"'),
+             (2, '#include "c.h"'),
+             (3, '#include "b.h"')]
+    mock_input_api = MockInputApi()
+    warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
+                                                    '', [2])
+    self.assertEqual(1, len(warnings))
+    self.assertTrue('3' in warnings[0])
+
+  def testConflictAdded2(self):
+    scope = [(1, '#include "c.h"'),
+             (2, '#include "b.h"'),
+             (3, '#include "d.h"')]
+    mock_input_api = MockInputApi()
+    warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
+                                                    '', [2])
+    self.assertEqual(1, len(warnings))
+    self.assertTrue('2' in warnings[0])
+
+  def testIfElifElseEndif(self):
+    mock_input_api = MockInputApi()
+    contents = ['#include "e.h"',
+                '#define foo',
+                '#include "f.h"',
+                '#undef foo',
+                '#include "e.h"',
+                '#if foo',
+                '#include "d.h"',
+                '#elif bar',
+                '#include "c.h"',
+                '#else',
+                '#include "b.h"',
+                '#endif',
+                '#include "a.h"']
+    mock_file = MockFile('', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+  def testExcludedIncludes(self):
+    # #include <sys/...>'s can appear in any order.
+    mock_input_api = MockInputApi()
+    contents = ['#include <sys/b.h>',
+                '#include <sys/a.h>']
+    mock_file = MockFile('', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+    contents = ['#include <atlbase.h>',
+                '#include <aaa.h>']
+    mock_file = MockFile('', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+    contents = ['#include "build/build_config.h"',
+                '#include "aaa.h"']
+    mock_file = MockFile('', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(0, len(warnings))
+
+  def testCheckOnlyCFiles(self):
+    mock_input_api = MockInputApi()
+    mock_output_api = MockOutputApi()
+    contents = ['#include <b.h>',
+                '#include <a.h>']
+    mock_file_cc = MockFile('something.cc', contents)
+    mock_file_h = MockFile('something.h', contents)
+    mock_file_other = MockFile('something.py', contents)
+    mock_input_api.files = [mock_file_cc, mock_file_h, mock_file_other]
+    warnings = PRESUBMIT._CheckIncludeOrder(mock_input_api, mock_output_api)
+    self.assertEqual(1, len(warnings))
+    self.assertEqual(2, len(warnings[0].items))
+    self.assertEqual('promptOrNotify', warnings[0].type)
+
+  def testUncheckableIncludes(self):
+    mock_input_api = MockInputApi()
+    contents = ['#include <windows.h>',
+                '#include "b.h"',
+                '#include "a.h"']
+    mock_file = MockFile('', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(1, len(warnings))
+
+    contents = ['#include "gpu/command_buffer/gles_autogen.h"',
+                '#include "b.h"',
+                '#include "a.h"']
+    mock_file = MockFile('', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(1, len(warnings))
+
+    contents = ['#include "gl_mock_autogen.h"',
+                '#include "b.h"',
+                '#include "a.h"']
+    mock_file = MockFile('', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(1, len(warnings))
+
+    contents = ['#include "ipc/some_macros.h"',
+                '#include "b.h"',
+                '#include "a.h"']
+    mock_file = MockFile('', contents)
+    warnings = PRESUBMIT._CheckIncludeOrderInFile(
+        mock_input_api, mock_file, range(1, len(contents) + 1))
+    self.assertEqual(1, len(warnings))
+
+
+class VersionControlConflictsTest(unittest.TestCase):
+  def testTypicalConflict(self):
+    lines = ['<<<<<<< HEAD',
+             '  base::ScopedTempDir temp_dir_;',
+             '=======',
+             '  ScopedTempDir temp_dir_;',
+             '>>>>>>> master']
+    errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
+        MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
+    self.assertEqual(3, len(errors))
+    self.assertTrue('1' in errors[0])
+    self.assertTrue('3' in errors[1])
+    self.assertTrue('5' in errors[2])
+
+  def testIgnoresReadmes(self):
+    lines = ['A First Level Header',
+             '====================',
+             '',
+             'A Second Level Header',
+             '---------------------']
+    errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
+        MockInputApi(), MockFile('some/polymer/README.md', lines))
+    self.assertEqual(0, len(errors))
+
+class UmaHistogramChangeMatchedOrNotTest(unittest.TestCase):
+  def testTypicalCorrectlyMatchedChange(self):
+    diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
+    diff_xml = ['<histogram name="Bla.Foo.Dummy"> </histogram>']
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('some/path/foo.cc', diff_cc),
+      MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
+    ]
+    warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
+                                                   MockOutputApi())
+    self.assertEqual(0, len(warnings))
+
+  def testTypicalNotMatchedChange(self):
+    diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [MockFile('some/path/foo.cc', diff_cc)]
+    warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
+                                                   MockOutputApi())
+    self.assertEqual(1, len(warnings))
+    self.assertEqual('warning', warnings[0].type)
+
+  def testTypicalNotMatchedChangeViaSuffixes(self):
+    diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
+    diff_xml = ['<histogram_suffixes name="SuperHistogram">',
+                '  <suffix name="Dummy"/>',
+                '  <affected-histogram name="Snafu.Dummy"/>',
+                '</histogram>']
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('some/path/foo.cc', diff_cc),
+      MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
+    ]
+    warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
+                                                   MockOutputApi())
+    self.assertEqual(1, len(warnings))
+    self.assertEqual('warning', warnings[0].type)
+
+  def testTypicalCorrectlyMatchedChangeViaSuffixes(self):
+    diff_cc = ['UMA_HISTOGRAM_BOOL("Bla.Foo.Dummy", true)']
+    diff_xml = ['<histogram_suffixes name="SuperHistogram">',
+                '  <suffix name="Dummy"/>',
+                '  <affected-histogram name="Bla.Foo"/>',
+                '</histogram>']
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('some/path/foo.cc', diff_cc),
+      MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
+    ]
+    warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
+                                                   MockOutputApi())
+    self.assertEqual(0, len(warnings))
+
+  def testTypicalCorrectlyMatchedChangeViaSuffixesWithSeparator(self):
+    diff_cc = ['UMA_HISTOGRAM_BOOL("Snafu_Dummy", true)']
+    diff_xml = ['<histogram_suffixes name="SuperHistogram" separator="_">',
+                '  <suffix name="Dummy"/>',
+                '  <affected-histogram name="Snafu"/>',
+                '</histogram>']
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('some/path/foo.cc', diff_cc),
+      MockFile('tools/metrics/histograms/histograms.xml', diff_xml),
+    ]
+    warnings = PRESUBMIT._CheckUmaHistogramChanges(mock_input_api,
+                                                   MockOutputApi())
+    self.assertEqual(0, len(warnings))
+
+class BadExtensionsTest(unittest.TestCase):
+  def testBadRejFile(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('some/path/foo.cc', ''),
+      MockFile('some/path/foo.cc.rej', ''),
+      MockFile('some/path2/bar.h.rej', ''),
+    ]
+
+    results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(results))
+    self.assertEqual(2, len(results[0].items))
+    self.assertTrue('foo.cc.rej' in results[0].items[0])
+    self.assertTrue('bar.h.rej' in results[0].items[1])
+
+  def testBadOrigFile(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('other/path/qux.h.orig', ''),
+      MockFile('other/path/qux.h', ''),
+      MockFile('other/path/qux.cc', ''),
+    ]
+
+    results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(results))
+    self.assertEqual(1, len(results[0].items))
+    self.assertTrue('qux.h.orig' in results[0].items[0])
+
+  def testGoodFiles(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('other/path/qux.h', ''),
+      MockFile('other/path/qux.cc', ''),
+    ]
+    results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(results))
+
+
+class CheckSingletonInHeadersTest(unittest.TestCase):
+  def testSingletonInArbitraryHeader(self):
+    diff_singleton_h = ['base::subtle::AtomicWord '
+                        'base::Singleton<Type, Traits, DifferentiatingType>::']
+    diff_foo_h = ['// base::Singleton<Foo> in comment.',
+                  'friend class base::Singleton<Foo>']
+    diff_bad_h = ['Foo* foo = base::Singleton<Foo>::get();']
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [MockAffectedFile('base/memory/singleton.h',
+                                     diff_singleton_h),
+                            MockAffectedFile('foo.h', diff_foo_h),
+                            MockAffectedFile('bad.h', diff_bad_h)]
+    warnings = PRESUBMIT._CheckSingletonInHeaders(mock_input_api,
+                                                  MockOutputApi())
+    self.assertEqual(1, len(warnings))
+    self.assertEqual('error', warnings[0].type)
+    self.assertTrue('Found base::Singleton<T>' in warnings[0].message)
+
+  def testSingletonInCC(self):
+    diff_cc = ['Foo* foo = base::Singleton<Foo>::get();']
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [MockAffectedFile('some/path/foo.cc', diff_cc)]
+    warnings = PRESUBMIT._CheckSingletonInHeaders(mock_input_api,
+                                                  MockOutputApi())
+    self.assertEqual(0, len(warnings))
+
+
+class InvalidOSMacroNamesTest(unittest.TestCase):
+  def testInvalidOSMacroNames(self):
+    lines = ['#if defined(OS_WINDOWS)',
+             ' #elif defined(OS_WINDOW)',
+             ' # if defined(OS_MACOSX) || defined(OS_CHROME)',
+             '# else  // defined(OS_MAC)',
+             '#endif  // defined(OS_MACOS)']
+    errors = PRESUBMIT._CheckForInvalidOSMacrosInFile(
+        MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
+    self.assertEqual(len(lines), len(errors))
+    self.assertTrue(':1 OS_WINDOWS' in errors[0])
+    self.assertTrue('(did you mean OS_WIN?)' in errors[0])
+
+  def testValidOSMacroNames(self):
+    lines = ['#if defined(%s)' % m for m in PRESUBMIT._VALID_OS_MACROS]
+    errors = PRESUBMIT._CheckForInvalidOSMacrosInFile(
+        MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
+    self.assertEqual(0, len(errors))
+
+
+class InvalidIfDefinedMacroNamesTest(unittest.TestCase):
+  def testInvalidIfDefinedMacroNames(self):
+    lines = ['#if defined(TARGET_IPHONE_SIMULATOR)',
+             '#if !defined(TARGET_IPHONE_SIMULATOR)',
+             '#elif defined(TARGET_IPHONE_SIMULATOR)',
+             '#ifdef TARGET_IPHONE_SIMULATOR',
+             ' # ifdef TARGET_IPHONE_SIMULATOR',
+             '# if defined(VALID) || defined(TARGET_IPHONE_SIMULATOR)',
+             '# else  // defined(TARGET_IPHONE_SIMULATOR)',
+             '#endif  // defined(TARGET_IPHONE_SIMULATOR)',]
+    errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
+        MockInputApi(), MockFile('some/path/source.mm', lines))
+    self.assertEqual(len(lines), len(errors))
+
+  def testValidIfDefinedMacroNames(self):
+    lines = ['#if defined(FOO)',
+             '#ifdef BAR',]
+    errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
+        MockInputApi(), MockFile('some/path/source.cc', lines))
+    self.assertEqual(0, len(errors))
+
+
+class CheckAddedDepsHaveTetsApprovalsTest(unittest.TestCase):
+  def testFilesToCheckForIncomingDeps(self):
+    changed_lines = [
+      '"+breakpad",',
+      '"+chrome/installer",',
+      '"+chrome/plugin/chrome_content_plugin_client.h",',
+      '"+chrome/utility/chrome_content_utility_client.h",',
+      '"+chromeos/chromeos_paths.h",',
+      '"+components/crash/content",',
+      '"+components/nacl/common",',
+      '"+content/public/browser/render_process_host.h",',
+      '"+jni/fooblat.h",',
+      '"+grit",  # For generated headers',
+      '"+grit/generated_resources.h",',
+      '"+grit/",',
+      '"+policy",  # For generated headers and source',
+      '"+sandbox",',
+      '"+tools/memory_watcher",',
+      '"+third_party/lss/linux_syscall_support.h",',
+    ]
+    files_to_check = PRESUBMIT._FilesToCheckForIncomingDeps(re, changed_lines)
+    expected = set([
+      'breakpad/DEPS',
+      'chrome/installer/DEPS',
+      'chrome/plugin/chrome_content_plugin_client.h',
+      'chrome/utility/chrome_content_utility_client.h',
+      'chromeos/chromeos_paths.h',
+      'components/crash/content/DEPS',
+      'components/nacl/common/DEPS',
+      'content/public/browser/render_process_host.h',
+      'policy/DEPS',
+      'sandbox/DEPS',
+      'tools/memory_watcher/DEPS',
+      'third_party/lss/linux_syscall_support.h',
+    ])
+    self.assertEqual(expected, files_to_check);
+
+
+class JSONParsingTest(unittest.TestCase):
+  def testSuccess(self):
+    input_api = MockInputApi()
+    filename = 'valid_json.json'
+    contents = ['// This is a comment.',
+                '{',
+                '  "key1": ["value1", "value2"],',
+                '  "key2": 3  // This is an inline comment.',
+                '}'
+                ]
+    input_api.files = [MockFile(filename, contents)]
+    self.assertEqual(None,
+                     PRESUBMIT._GetJSONParseError(input_api, filename))
+
+  def testFailure(self):
+    input_api = MockInputApi()
+    test_data = [
+      ('invalid_json_1.json',
+       ['{ x }'],
+       'Expecting property name:'),
+      ('invalid_json_2.json',
+       ['// Hello world!',
+        '{ "hello": "world }'],
+       'Unterminated string starting at:'),
+      ('invalid_json_3.json',
+       ['{ "a": "b", "c": "d", }'],
+       'Expecting property name:'),
+      ('invalid_json_4.json',
+       ['{ "a": "b" "c": "d" }'],
+       'Expecting , delimiter:'),
+      ]
+
+    input_api.files = [MockFile(filename, contents)
+                       for (filename, contents, _) in test_data]
+
+    for (filename, _, expected_error) in test_data:
+      actual_error = PRESUBMIT._GetJSONParseError(input_api, filename)
+      self.assertTrue(expected_error in str(actual_error),
+                      "'%s' not found in '%s'" % (expected_error, actual_error))
+
+  def testNoEatComments(self):
+    input_api = MockInputApi()
+    file_with_comments = 'file_with_comments.json'
+    contents_with_comments = ['// This is a comment.',
+                              '{',
+                              '  "key1": ["value1", "value2"],',
+                              '  "key2": 3  // This is an inline comment.',
+                              '}'
+                              ]
+    file_without_comments = 'file_without_comments.json'
+    contents_without_comments = ['{',
+                                 '  "key1": ["value1", "value2"],',
+                                 '  "key2": 3',
+                                 '}'
+                                 ]
+    input_api.files = [MockFile(file_with_comments, contents_with_comments),
+                       MockFile(file_without_comments,
+                                contents_without_comments)]
+
+    self.assertEqual('No JSON object could be decoded',
+                     str(PRESUBMIT._GetJSONParseError(input_api,
+                                                      file_with_comments,
+                                                      eat_comments=False)))
+    self.assertEqual(None,
+                     PRESUBMIT._GetJSONParseError(input_api,
+                                                  file_without_comments,
+                                                  eat_comments=False))
+
+
+class IDLParsingTest(unittest.TestCase):
+  def testSuccess(self):
+    input_api = MockInputApi()
+    filename = 'valid_idl_basics.idl'
+    contents = ['// Tests a valid IDL file.',
+                'namespace idl_basics {',
+                '  enum EnumType {',
+                '    name1,',
+                '    name2',
+                '  };',
+                '',
+                '  dictionary MyType1 {',
+                '    DOMString a;',
+                '  };',
+                '',
+                '  callback Callback1 = void();',
+                '  callback Callback2 = void(long x);',
+                '  callback Callback3 = void(MyType1 arg);',
+                '  callback Callback4 = void(EnumType type);',
+                '',
+                '  interface Functions {',
+                '    static void function1();',
+                '    static void function2(long x);',
+                '    static void function3(MyType1 arg);',
+                '    static void function4(Callback1 cb);',
+                '    static void function5(Callback2 cb);',
+                '    static void function6(Callback3 cb);',
+                '    static void function7(Callback4 cb);',
+                '  };',
+                '',
+                '  interface Events {',
+                '    static void onFoo1();',
+                '    static void onFoo2(long x);',
+                '    static void onFoo2(MyType1 arg);',
+                '    static void onFoo3(EnumType type);',
+                '  };',
+                '};'
+                ]
+    input_api.files = [MockFile(filename, contents)]
+    self.assertEqual(None,
+                     PRESUBMIT._GetIDLParseError(input_api, filename))
+
+  def testFailure(self):
+    input_api = MockInputApi()
+    test_data = [
+      ('invalid_idl_1.idl',
+       ['//',
+        'namespace test {',
+        '  dictionary {',
+        '    DOMString s;',
+        '  };',
+        '};'],
+       'Unexpected "{" after keyword "dictionary".\n'),
+      # TODO(yoz): Disabled because it causes the IDL parser to hang.
+      # See crbug.com/363830.
+      # ('invalid_idl_2.idl',
+      #  (['namespace test {',
+      #    '  dictionary MissingSemicolon {',
+      #    '    DOMString a',
+      #    '    DOMString b;',
+      #    '  };',
+      #    '};'],
+      #   'Unexpected symbol DOMString after symbol a.'),
+      ('invalid_idl_3.idl',
+       ['//',
+        'namespace test {',
+        '  enum MissingComma {',
+        '    name1',
+        '    name2',
+        '  };',
+        '};'],
+       'Unexpected symbol name2 after symbol name1.'),
+      ('invalid_idl_4.idl',
+       ['//',
+        'namespace test {',
+        '  enum TrailingComma {',
+        '    name1,',
+        '    name2,',
+        '  };',
+        '};'],
+       'Trailing comma in block.'),
+      ('invalid_idl_5.idl',
+       ['//',
+        'namespace test {',
+        '  callback Callback1 = void(;',
+        '};'],
+       'Unexpected ";" after "(".'),
+      ('invalid_idl_6.idl',
+       ['//',
+        'namespace test {',
+        '  callback Callback1 = void(long );',
+        '};'],
+       'Unexpected ")" after symbol long.'),
+      ('invalid_idl_7.idl',
+       ['//',
+        'namespace test {',
+        '  interace Events {',
+        '    static void onFoo1();',
+        '  };',
+        '};'],
+       'Unexpected symbol Events after symbol interace.'),
+      ('invalid_idl_8.idl',
+       ['//',
+        'namespace test {',
+        '  interface NotEvent {',
+        '    static void onFoo1();',
+        '  };',
+        '};'],
+       'Did not process Interface Interface(NotEvent)'),
+      ('invalid_idl_9.idl',
+       ['//',
+        'namespace test {',
+        '  interface {',
+        '    static void function1();',
+        '  };',
+        '};'],
+       'Interface missing name.'),
+      ]
+
+    input_api.files = [MockFile(filename, contents)
+                       for (filename, contents, _) in test_data]
+
+    for (filename, _, expected_error) in test_data:
+      actual_error = PRESUBMIT._GetIDLParseError(input_api, filename)
+      self.assertTrue(expected_error in str(actual_error),
+                      "'%s' not found in '%s'" % (expected_error, actual_error))
+
+
+class TryServerMasterTest(unittest.TestCase):
+  def testTryServerMasters(self):
+    bots = {
+        'tryserver.chromium.mac': [
+            'ios_dbg_simulator',
+            'ios_rel_device',
+            'ios_rel_device_ninja',
+            'mac_asan',
+            'mac_asan_64',
+            'mac_chromium_compile_dbg',
+            'mac_chromium_compile_rel',
+            'mac_chromium_dbg',
+            'mac_chromium_rel',
+            'mac_nacl_sdk',
+            'mac_nacl_sdk_build',
+            'mac_rel_naclmore',
+            'mac_valgrind',
+            'mac_x64_rel',
+            'mac_xcodebuild',
+        ],
+        'tryserver.chromium.linux': [
+            'android_aosp',
+            'android_chromium_gn_compile_dbg',
+            'android_chromium_gn_compile_rel',
+            'android_clang_dbg',
+            'android_dbg',
+            'android_dbg_recipe',
+            'android_dbg_triggered_tests',
+            'android_dbg_triggered_tests_recipe',
+            'android_fyi_dbg',
+            'android_fyi_dbg_triggered_tests',
+            'android_rel',
+            'android_rel_triggered_tests',
+            'android_x86_dbg',
+            'blink_android_compile_dbg',
+            'blink_android_compile_rel',
+            'blink_presubmit',
+            'chromium_presubmit',
+            'linux_arm_cross_compile',
+            'linux_arm_tester',
+            'linux_chromeos_asan',
+            'linux_chromeos_browser_asan',
+            'linux_chromeos_valgrind',
+            'linux_chromium_chromeos_dbg',
+            'linux_chromium_chromeos_rel',
+            'linux_chromium_compile_dbg',
+            'linux_chromium_compile_rel',
+            'linux_chromium_dbg',
+            'linux_chromium_gn_dbg',
+            'linux_chromium_gn_rel',
+            'linux_chromium_rel',
+            'linux_chromium_trusty32_dbg',
+            'linux_chromium_trusty32_rel',
+            'linux_chromium_trusty_dbg',
+            'linux_chromium_trusty_rel',
+            'linux_clang_tsan',
+            'linux_ecs_ozone',
+            'linux_layout',
+            'linux_layout_asan',
+            'linux_layout_rel',
+            'linux_layout_rel_32',
+            'linux_nacl_sdk',
+            'linux_nacl_sdk_bionic',
+            'linux_nacl_sdk_bionic_build',
+            'linux_nacl_sdk_build',
+            'linux_redux',
+            'linux_rel_naclmore',
+            'linux_rel_precise32',
+            'linux_valgrind',
+            'tools_build_presubmit',
+        ],
+        'tryserver.chromium.win': [
+            'win8_aura',
+            'win8_chromium_dbg',
+            'win8_chromium_rel',
+            'win_chromium_compile_dbg',
+            'win_chromium_compile_rel',
+            'win_chromium_dbg',
+            'win_chromium_rel',
+            'win_chromium_rel',
+            'win_chromium_x64_dbg',
+            'win_chromium_x64_rel',
+            'win_drmemory',
+            'win_nacl_sdk',
+            'win_nacl_sdk_build',
+            'win_rel_naclmore',
+         ],
+    }
+    for master, bots in bots.iteritems():
+      for bot in bots:
+        self.assertEqual(master, PRESUBMIT.GetTryServerMasterForBot(bot),
+                         'bot=%s: expected %s, computed %s' % (
+            bot, master, PRESUBMIT.GetTryServerMasterForBot(bot)))
+
+
+class UserMetricsActionTest(unittest.TestCase):
+  def testUserMetricsActionInActions(self):
+    input_api = MockInputApi()
+    file_with_user_action = 'file_with_user_action.cc'
+    contents_with_user_action = [
+      'base::UserMetricsAction("AboutChrome")'
+    ]
+
+    input_api.files = [MockFile(file_with_user_action,
+                                contents_with_user_action)]
+
+    self.assertEqual(
+      [], PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi()))
+
+
+  def testUserMetricsActionNotAddedToActions(self):
+    input_api = MockInputApi()
+    file_with_user_action = 'file_with_user_action.cc'
+    contents_with_user_action = [
+      'base::UserMetricsAction("NotInActionsXml")'
+    ]
+
+    input_api.files = [MockFile(file_with_user_action,
+                                contents_with_user_action)]
+
+    output = PRESUBMIT._CheckUserActionUpdate(input_api, MockOutputApi())
+    self.assertEqual(
+      ('File %s line %d: %s is missing in '
+       'tools/metrics/actions/actions.xml. Please run '
+       'tools/metrics/actions/extract_actions.py to update.'
+       % (file_with_user_action, 1, 'NotInActionsXml')),
+      output[0].message)
+
+
+class LogUsageTest(unittest.TestCase):
+
+  def testCheckAndroidCrLogUsage(self):
+    mock_input_api = MockInputApi()
+    mock_output_api = MockOutputApi()
+
+    mock_input_api.files = [
+      MockAffectedFile('RandomStuff.java', [
+        'random stuff'
+      ]),
+      MockAffectedFile('HasAndroidLog.java', [
+        'import android.util.Log;',
+        'some random stuff',
+        'Log.d("TAG", "foo");',
+      ]),
+      MockAffectedFile('HasExplicitUtilLog.java', [
+        'some random stuff',
+        'android.util.Log.d("TAG", "foo");',
+      ]),
+      MockAffectedFile('IsInBasePackage.java', [
+        'package org.chromium.base;',
+        'private static final String TAG = "cr_Foo";',
+        'Log.d(TAG, "foo");',
+      ]),
+      MockAffectedFile('IsInBasePackageButImportsLog.java', [
+        'package org.chromium.base;',
+        'import android.util.Log;',
+        'private static final String TAG = "cr_Foo";',
+        'Log.d(TAG, "foo");',
+      ]),
+      MockAffectedFile('HasBothLog.java', [
+        'import org.chromium.base.Log;',
+        'some random stuff',
+        'private static final String TAG = "cr_Foo";',
+        'Log.d(TAG, "foo");',
+        'android.util.Log.d("TAG", "foo");',
+      ]),
+      MockAffectedFile('HasCorrectTag.java', [
+        'import org.chromium.base.Log;',
+        'some random stuff',
+        'private static final String TAG = "cr_Foo";',
+        'Log.d(TAG, "foo");',
+      ]),
+      MockAffectedFile('HasOldTag.java', [
+        'import org.chromium.base.Log;',
+        'some random stuff',
+        'private static final String TAG = "cr.Foo";',
+        'Log.d(TAG, "foo");',
+      ]),
+      MockAffectedFile('HasDottedTag.java', [
+        'import org.chromium.base.Log;',
+        'some random stuff',
+        'private static final String TAG = "cr_foo.bar";',
+        'Log.d(TAG, "foo");',
+      ]),
+      MockAffectedFile('HasNoTagDecl.java', [
+        'import org.chromium.base.Log;',
+        'some random stuff',
+        'Log.d(TAG, "foo");',
+      ]),
+      MockAffectedFile('HasIncorrectTagDecl.java', [
+        'import org.chromium.base.Log;',
+        'private static final String TAHG = "cr_Foo";',
+        'some random stuff',
+        'Log.d(TAG, "foo");',
+      ]),
+      MockAffectedFile('HasInlineTag.java', [
+        'import org.chromium.base.Log;',
+        'some random stuff',
+        'private static final String TAG = "cr_Foo";',
+        'Log.d("TAG", "foo");',
+      ]),
+      MockAffectedFile('HasUnprefixedTag.java', [
+        'import org.chromium.base.Log;',
+        'some random stuff',
+        'private static final String TAG = "rubbish";',
+        'Log.d(TAG, "foo");',
+      ]),
+      MockAffectedFile('HasTooLongTag.java', [
+        'import org.chromium.base.Log;',
+        'some random stuff',
+        'private static final String TAG = "21_charachers_long___";',
+        'Log.d(TAG, "foo");',
+      ]),
+    ]
+
+    msgs = PRESUBMIT._CheckAndroidCrLogUsage(
+        mock_input_api, mock_output_api)
+
+    self.assertEqual(5, len(msgs),
+                     'Expected %d items, found %d: %s' % (5, len(msgs), msgs))
+
+    # Declaration format
+    nb = len(msgs[0].items)
+    self.assertEqual(2, nb,
+                     'Expected %d items, found %d: %s' % (2, nb, msgs[0].items))
+    self.assertTrue('HasNoTagDecl.java' in msgs[0].items)
+    self.assertTrue('HasIncorrectTagDecl.java' in msgs[0].items)
+
+    # Tag length
+    nb = len(msgs[1].items)
+    self.assertEqual(1, nb,
+                     'Expected %d items, found %d: %s' % (1, nb, msgs[1].items))
+    self.assertTrue('HasTooLongTag.java' in msgs[1].items)
+
+    # Tag must be a variable named TAG
+    nb = len(msgs[2].items)
+    self.assertEqual(1, nb,
+                     'Expected %d items, found %d: %s' % (1, nb, msgs[2].items))
+    self.assertTrue('HasInlineTag.java:4' in msgs[2].items)
+
+    # Util Log usage
+    nb = len(msgs[3].items)
+    self.assertEqual(2, nb,
+                     'Expected %d items, found %d: %s' % (2, nb, msgs[3].items))
+    self.assertTrue('HasAndroidLog.java:3' in msgs[3].items)
+    self.assertTrue('IsInBasePackageButImportsLog.java:4' in msgs[3].items)
+
+    # Tag must not contain
+    nb = len(msgs[4].items)
+    self.assertEqual(2, nb,
+                     'Expected %d items, found %d: %s' % (2, nb, msgs[4].items))
+    self.assertTrue('HasDottedTag.java' in msgs[4].items)
+    self.assertTrue('HasOldTag.java' in msgs[4].items)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/PRESUBMIT_test_mocks.py b/PRESUBMIT_test_mocks.py
new file mode 100644
index 0000000..8e15d8c
--- /dev/null
+++ b/PRESUBMIT_test_mocks.py
@@ -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.
+
+import json
+import os
+import re
+import subprocess
+import sys
+
+
+class MockInputApi(object):
+  """Mock class for the InputApi class.
+
+  This class can be used for unittests for presubmit by initializing the files
+  attribute as the list of changed files.
+  """
+
+  def __init__(self):
+    self.json = json
+    self.re = re
+    self.os_path = os.path
+    self.python_executable = sys.executable
+    self.subprocess = subprocess
+    self.files = []
+    self.is_committing = False
+    self.change = MockChange([])
+
+  def AffectedFiles(self, file_filter=None):
+    return self.files
+
+  def AffectedSourceFiles(self, file_filter=None):
+    return self.files
+
+  def LocalPaths(self):
+    return self.files
+
+  def PresubmitLocalPath(self):
+    return os.path.dirname(__file__)
+
+  def ReadFile(self, filename, mode='rU'):
+    if hasattr(filename, 'AbsoluteLocalPath'):
+       filename = filename.AbsoluteLocalPath()
+    for file_ in self.files:
+      if file_.LocalPath() == filename:
+        return '\n'.join(file_.NewContents())
+    # Otherwise, file is not in our mock API.
+    raise IOError, "No such file or directory: '%s'" % filename
+
+
+class MockOutputApi(object):
+  """Mock class for the OutputApi class.
+
+  An instance of this class can be passed to presubmit unittests for outputing
+  various types of results.
+  """
+
+  class PresubmitResult(object):
+    def __init__(self, message, items=None, long_text=''):
+      self.message = message
+      self.items = items
+      self.long_text = long_text
+
+    def __repr__(self):
+      return self.message
+
+  class PresubmitError(PresubmitResult):
+    def __init__(self, message, items=None, long_text=''):
+      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
+      self.type = 'error'
+
+  class PresubmitPromptWarning(PresubmitResult):
+    def __init__(self, message, items=None, long_text=''):
+      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
+      self.type = 'warning'
+
+  class PresubmitNotifyResult(PresubmitResult):
+    def __init__(self, message, items=None, long_text=''):
+      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
+      self.type = 'notify'
+
+  class PresubmitPromptOrNotify(PresubmitResult):
+    def __init__(self, message, items=None, long_text=''):
+      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
+      self.type = 'promptOrNotify'
+
+
+class MockFile(object):
+  """Mock class for the File class.
+
+  This class can be used to form the mock list of changed files in
+  MockInputApi for presubmit unittests.
+  """
+
+  def __init__(self, local_path, new_contents):
+    self._local_path = local_path
+    self._new_contents = new_contents
+    self._changed_contents = [(i + 1, l) for i, l in enumerate(new_contents)]
+
+  def ChangedContents(self):
+    return self._changed_contents
+
+  def NewContents(self):
+    return self._new_contents
+
+  def LocalPath(self):
+    return self._local_path
+
+  def rfind(self, p):
+    """os.path.basename is called on MockFile so we need an rfind method."""
+    return self._local_path.rfind(p)
+
+  def __getitem__(self, i):
+    """os.path.basename is called on MockFile so we need a get method."""
+    return self._local_path[i]
+
+
+class MockAffectedFile(MockFile):
+  def AbsoluteLocalPath(self):
+    return self._local_path
+
+
+class MockChange(object):
+  """Mock class for Change class.
+
+  This class can be used in presubmit unittests to mock the query of the
+  current change.
+  """
+
+  def __init__(self, changed_files):
+    self._changed_files = changed_files
+
+  def LocalPaths(self):
+    return self._changed_files
diff --git a/WATCHLISTS b/WATCHLISTS
new file mode 100644
index 0000000..08b4f9a
--- /dev/null
+++ b/WATCHLISTS
@@ -0,0 +1,1173 @@
+# 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.
+
+# Watchlist Rules
+# Refer: http://dev.chromium.org/developers/contributing-code/watchlists
+
+# IMPORTANT: The regular expression filepath is tested against each path using
+# re.search, so it is not usually necessary to add .*.
+
+{
+  'WATCHLIST_DEFINITIONS': {
+    'accelerator_table': {
+      'filepath': 'ash/accelerators/accelerator_table\.cc' \
+                  '|chrome/browser/ui/views/accelerator_table\.cc',
+    },
+    'accessibility': {
+      'filepath': 'accessibility' \
+                  '|braille' \
+                  '|chromevox' \
+                  '|iaccessible2' \
+                  '|isimpledom' \
+                  '|liblouis'
+    },
+    'activity_log': {
+      'filepath': 'chrome/browser/extensions/activity_log/' \
+                  '|chrome/browser/extensions/api/activity_log_private/'
+    },
+    'android_infra': {
+      'filepath': 'build/android/' \
+                  '|testing/android/' \
+                  '|tools/android/'
+    },
+    'android_media': {
+      'filepath': 'content/browser/media/android' \
+                  '|content/renderer/media/android' \
+                  '|media/audio/android' \
+                  '|media/base/android' \
+                  '|media/midi/*_android.*' \
+                  '|media/video/capture/android'
+    },
+    'android_tab': {
+      'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/Tab'
+    },
+    'android_webview': {
+      'filepath': 'android_webview/',
+    },
+    'app_list': {
+      'filepath': 'chrome/browser/ui/app_list'\
+                  '|chrome/browser/ui/ash/app_list'\
+                  '|chrome/browser/ui/views/app_list'\
+                  '|ui/app_list/'
+    },
+    'app_shortcuts': {
+      'filepath': 'apps/app_shim/'\
+                  '|chrome/browser/web_applications/'\
+                  '|chrome/browser/ui/web_applications/'\
+                  '|chrome/common/mac/'
+    },
+    'appcache': {
+      'filepath': 'appcache/',
+    },
+    'apps': {
+      'filepath': '^apps/',
+    },
+    'ash': {
+      'filepath': 'ash/',
+    },
+    'aura': {
+      'filepath': 'ui/aura/',
+    },
+    'aura_compositor': {
+      'filepath':
+        'ui/compositor/' \
+        '|content/browser/compositor/' \
+        '|content/browser/renderer_host/compositor_resize_lock_aura' \
+        '|content/browser/renderer_host/render_widget_host_view_aura' \
+        '|content/browser/renderer_host/render_widget_host_view_browsertest' \
+        '|content/browser/renderer_host/delegated' \
+        '|content/browser/renderer_host/software' \
+        '|content/common/gpu/client/' \
+    },
+    'auto_bisect': {
+      'filepath': 'tools/run-bisect-perf-regression.py'\
+                  '|tools/run-perf-test.cfg'\
+                  '|tools/auto_bisect/'
+    },
+    'autofill': {
+      'filepath': 'chrome/browser/autofill/|'\
+                  'chrome/browser/resources/options/autofill_|'\
+                  'chrome/browser/sync/glue/autofill_|'\
+                  'chrome/browser/ui/android/autofill/|'\
+                  'chrome/browser/ui/autofill/|'\
+                  'chrome/browser/ui/cocoa/autofill/|'\
+                  'chrome/browser/ui/gtk/autofill/|'\
+                  'chrome/browser/ui/views/autofill/|'\
+                  'chrome/browser/ui/webui/options/autofill_|'\
+                  'chrome/renderer/autofill/|'\
+                  'chrome/test/data/autofill/|'\
+                  'components/autofill/|'\
+                  'components/autofill/browser/webdata/|'\
+                  'components/webdata/|'\
+                  'content/public/common/password_|'\
+                  'content/public/renderer/password_|'\
+                  'content/renderer/password_',
+    },
+    'automation': {
+      'filepath': 'chrome/browser/automation/|chrome/test/automation/',
+    },
+    'background_sync': {
+      'filepath': 'background_sync',
+    },
+    'base': {
+      'filepath': '^base/',
+    },
+    'base_allocator': {
+      'filepath': '^base/allocator',
+    },
+    'base_memory': {
+      'filepath': '^base/memory',
+    },
+    'base_win': {
+      'filepath': '^base/win',
+    },
+    'battery_status': {
+      'filepath': 'content/browser/battery_status/|'\
+                  'content/renderer/battery_status/|'\
+                  'content/test/data/battery_status/|'\
+                  'device/battery/',
+    },
+    'blimp': {
+      'filepath': '^blimp/',
+    },
+    'bookmarks': {
+      'filepath': 'chrome/browser/bookmarks/' \
+                  '|chrome/browser/extensions/api/bookmark_manager_private/' \
+                  '|chrome/browser/extensions/api/bookmarks/' \
+                  '|chrome/browser/resources/bookmark_manager/' \
+                  '|chrome/browser/ui/bookmarks/' \
+                  '|chrome/browser/ui/cocoa/bookmarks/' \
+                  '|chrome/browser/ui/views/bookmarks/' \
+                  '|components/bookmarks'
+    },
+    'breakpad_app': {
+      'filepath': 'components/crash/content/app/',
+    },
+    'browser': {
+      'filepath': 'chrome/browser/',
+    },
+    'browser_chromeos': {
+      'filepath': 'chrome/browser/chromeos/',
+    },
+    'browser_components': {
+      'filepath': 'chrome/browser/autofill/' \
+                  '|chrome/browser/bookmarks/' \
+                  '|chrome/browser/favicon/' \
+                  '|chrome/browser/history/' \
+                  '|chrome/browser/webdata/' \
+                  '|components/autofill/'
+    },
+    'browser_compositor': {
+      'filepath': 'ui/compositor/'
+    },
+    'browser_resources': {
+      'filepath': 'chrome/browser/resources/',
+    },
+    'browsing_data': {
+      'filepath': 'chrome/browser/browsing_data/',
+    },
+    'bubble': {
+      'filepath': 'ui/views/bubble/|'\
+                  'chrome/browser/ui/views/bubble/|'\
+                  'components/bubble/',
+    },
+    'cache_storage': {
+      'filepath': 'cache_storage',
+    },
+    'cast': {
+      'filepath': 'media/cast/'\
+                  '|chrome/browser/extensions/api/cast_streaming/'\
+                  '|chrome/browser/media/cast'\
+                  '|chrome/renderer/media/cast'\
+                  '|chrome/test/data/extensions/api_test/cast_'\
+                  '|content/public/renderer/media_stream_',
+    },
+    'chromecast': {
+      'filepath': 'chromecast/',
+    },
+    'cc': {
+      'filepath': 'cc/|'\
+                  'content/common/cc_messages'
+    },
+    'chrome_elf': {
+      'filepath': 'chrome_elf',
+    },
+    'chrome_views': {
+      'filepath': 'chrome/browser/ui/views',
+    },
+    'chromedriver': {
+      'filepath': 'chrome/test/chromedriver|'\
+                  'chrome/test/data/chromedriver|'\
+                  'third_party/webdriver'
+    },
+    'chromeos': {
+      'filepath': 'chromeos/',
+    },
+    'chromeos_attestation': {
+      'filepath': 'chromeos/attestation/|'\
+                  'chrome/browser/chromeos/attestation/|'\
+                  'chrome/browser/extensions/api/enterprise_platform_keys_private/',
+    },
+    'chromeos_calculator': {
+      'filepath': 'chrome/common/extensions/docs/examples/apps/calculator/',
+    },
+    'chromeos_dbus': {
+      'filepath': 'chromeos/dbus/',
+    },
+    'chromeos_login': {
+      'filepath': 'chrome/browser/chromeos/login/|'\
+                  'chrome/browser/ui/webui/chromeos/login/|'\
+                  'chrome/browser/resources/chromeos/login/|'\
+                  'ui/login/',
+    },
+    'chromeos_net': {
+      'filepath': 'chromeos/network/|'\
+                  'chrome/browser/chromeos/net/|'\
+                  'chrome/browser/extensions/api/networking_private/|'\
+                  'extensions/browser/api/networking_private/|'\
+                  'ui/chromeos/network/',
+    },
+    'chromeos_power': {
+      'filepath': 'ash/system/chromeos/power/|'\
+                  'chromeos/dbus/power_.*|'\
+                  'chrome/browser/chromeos/power/',
+    },
+    'chromeos_webui': {
+      'filepath': 'chrome/browser/ui/webui/chromeos/|'\
+                  'chrome/browser/resources/chromeos/',
+    },
+    'clang_update': {
+      'filepath': 'tools/clang/scripts/update.sh'
+    },
+    'clipboard': {
+      'filepath': 'clipboard|dnd|drag|drop',
+    },
+    'closure': {
+      'filepath': 'third_party/closure_(compiler|linter)/|'
+                  'compiled_resources.gyp',
+    },
+    'components_deps': {
+      'filepath': 'components/([^/]*/)*DEPS',
+    },
+    'content': {
+      'filepath': 'content/',
+    },
+    'content_bluetooth': {
+      'filepath': 'content/.*bluetooth'
+    },
+    'content_input': {
+      'filepath': 'content/browser/renderer_host/input/|'\
+                  'content/common/input/|'\
+                  'content/renderer/input/',
+    },
+    'content_renderer': {
+      'filepath': 'content/renderer/',
+    },
+    'content_shell': {
+      'filepath': 'content/shell/',
+    },
+    'content_worker': {
+      'filepath': 'content/.*worker',
+    },
+    'cookie_monster': {
+      'filepath': 'net/cookies/|'\
+                  'chrome/browser/net/sqlite_persistent_cookie_store',
+    },
+    'custom_handlers': {
+      'filepath': 'chrome/browser/custom_handlers/|'\
+                  'chrome/common/custom_handlers/',
+    },
+    'custom_tabs': {
+      'filepath': 'chrome/android/java/src/org/chromium/chrome/browser/customtabs/|'\
+                  'chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/',
+    },
+    'deep_memory_profiler': {
+      'filepath': 'tools/(deep_memory_profiler|find_runtime_symbols)',
+    },
+    'device_bluetooth': {
+      'filepath': 'device/.*bluetooth'
+    },
+    'device_sensors': {
+      'filepath': 'content/browser/device_sensors/|'\
+                  'content/common/device_sensors/|'\
+                  'content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java|'\
+                  'content/public/android/javatests/src/org/chromium/content/browser/DeviceSensorsTest.java|'\
+                  'content/renderer/device_sensors/',
+    },
+    'developer_recommended_flags': {
+      'filepath': 'developer_recommended_flags.gypi',
+    },
+    'devtools': {
+      'filepath': 'devtools',
+    },
+    'disk_cache': {
+      'filepath': 'net/disk_cache/|http_cache',
+    },
+    'dns': {
+      'filepath': 'net/base/host_resolver|' \
+                  'net/base/host_cache|' \
+                  'net/dns/'
+    },
+    'download': {
+      'filepath': 'chrome/browser/download/|'\
+                  'content/browser/download/',
+    },
+    'download_database': {
+      'filepath': 'chrome/browser/history/download_database',
+    },
+    'downloads_ext': {
+      'filepath': 'chrome/browser/extensions/api/downloads/|'\
+                  'chrome/common/extensions/api/downloads.*.idl',
+    },
+    'downloads_ui': {
+      'filepath': 'chrome/browser/resources/downloads/|' \
+                  'chrome/browser/ui/webui/.*downloads|' \
+                  'chrome/browser/ui/views/download/|' \
+                  'chrome/browser/ui/cocoa/download/|' \
+                  'chrome/browser/ui/gtk/download/'
+    },
+    'drive': {
+      'filepath': 'chrome/browser/chromeos/drive/|' \
+                  'chrome/browser/google_apis/'
+    },
+    'drive_resource_metadata': {
+      'filepath': 'chrome/browser/chromeos/drive/resource_metadata'
+    },
+    'eme': {
+      'filepath': 'components/cdm/|' \
+                  'content/browser/media/cdm/|' \
+                  'content/renderer/media/crypto/|' \
+                  'media/base/android/*drm*|' \
+                  'media/cdm/|' \
+                  'third_party/widevine/cdm/'
+    },
+    'enhanced_bookmarks': {
+      'filepath': 'chrome/browser/enhanced_bookmarks/' \
+                  '|components/enhanced_bookmarks/'
+    },
+    'enhanced_bookmarks_android': {
+      'filepath': 'chrome/android/java/src/org/chromium/'\
+                    'chrome/browser/enhancedbookmarks/|'\
+                  'chrome/android/java/res/layout/eb*.xml'
+    },
+    'events': {
+      'filepath': 'ui/events/',
+    },
+    'extension': {
+      'filepath': 'extension',
+    },
+    'fileapi': {
+      'filepath': 'file_system/|' \
+                  'fileapi/'
+    },
+    'filebrowse': {
+      'filepath': 'file_browser|' \
+                  'file_manager|' \
+                  'filebrowse'
+    },
+    'filesapp': {
+      'filepath': 'ui/file_manager'
+    },
+    'ftp': {
+      'filepath': 'ftp',
+    },
+    'gcm': {
+      'filepath': 'chrome/browser/services/gcm/|'\
+                  'components/gcm_driver/|'\
+                  'google_apis/gcm/',
+    },
+    'geolocation': {
+      'filepath': 'chrome/browser/geolocation/|'\
+                  'content/browser/geolocation|'\
+                  'content/public/common/geoposition.*|'\
+                  'content/public/browser/geolocation.*|'\
+                  'content/renderer/geolocation.*|'\
+                  'content/shell/geolocation/',
+    },
+    'gfx_image': {
+      'filepath': 'ui/gfx/image/',
+    },
+    'gfx_geometry': {
+      'filepath': 'ui/gfx/geometry/',
+    },
+    'gn': {
+      'filepath': 'tools/gn',
+    },
+    'gpu': {
+      'filepath': 'gpu/',
+    },
+    'history_ui': {
+      'filepath': 'chrome/browser/resources/history',
+    },
+    'hotword': {
+      'filepath': 'chrome/browser/extensions/api/hotword_private/'\
+                  '|chrome/browser/resources/hotword_helper/'\
+                  '|chrome/browser/resources/hotword/'\
+                  '|chrome/browser/search/hotword*'\
+                  '|chrome/test/data/extensions/api_test/hotword_private/',
+    },
+    'i18n': {
+      'filepath': 'base/i18n/|base/string|l10n|icu|'\
+        'locale_settings|encoding',
+    },
+    'importer': {
+      'filepath': 'import',
+    },
+    'indexed_db': {
+      'filepath': 'content/browser/indexed_db|'\
+                  'content/child/indexed_db|'\
+                  'content/common/indexed_db|'\
+                  'content/public/browser/indexed_db|'\
+                  'content/test/data/indexeddb',
+    },
+    'installer': {
+      'filepath': 'chrome/installer/',
+    },
+    'installer_linux': {
+      'filepath': 'chrome/installer/linux/',
+    },
+    'instant': {
+      'filepath': 'instant|searchbox|'\
+                  'chrome/browser/search/|'\
+                  'chrome/browser/ui/search/|'\
+                  'chrome/browser/resources/local_ntp/|'\
+                  'chrome/common/search_types.*',
+    },
+    'ios_chrome': {
+      'filepath': 'ios/chrome',
+    },
+    'ipc': {
+      'filepath': 'ipc/ipc',
+    },
+    'ipc_messages': {
+      'filepath': '_message.*.h|'\
+                  '_messages.cc',
+    },
+    'libwebp': {
+      'filepath': 'third_party/libwebp'
+    },
+    'libvpx': {
+      'filepath': 'third_party/libvpx_new'
+    },
+    'linux_fonts': {
+      'filepath': 'ui/gfx/font_render_params_.*|'\
+                  'ui/gfx/platform_font_linux.*|'\
+                  'ui/gfx/render_text_harfbuzz.*',
+    },
+    'linux_sandboxing': {
+      'filepath': 'sandbox/linux/',
+    },
+    'linux_seccomp_bpf': {
+      'filepath': 'content/common/sandbox.*linux.cc',
+    },
+    'mandoline': {
+      'filepath': 'mandoline',
+    },
+    'manifest': {
+      'filepath': 'content/(browser|renderer)/manifest/'\
+                  '|content/public/common/manifest*',
+    },
+    'md_settings': {
+      'filepath': 'ui/webui/resources/cr_element'\
+                  '|chrome/browser/resources/settings/'\
+                  '|chrome/browser/ui/webui/settings/',
+    },
+    'media': {
+      'filepath': 'media/|third_party/(ffmpeg|openmax)/|webmediaplayer|'\
+        'audio_message_filter|video_layer|media_internals',
+    },
+    'media_galleries': {
+      'filepath': 'chrome/browser/extensions/api/media_galleries/'\
+                  '|chrome/browser/media_galleries/'\
+                  '|chrome/browser/storage_monitor/'\
+                  '|chrome/common/media_galleries/'\
+                  '|chrome/test/data/extensions/api_test/media_galleries/'\
+                  '|chrome/utility/itunes*'\
+                  '|chrome/utility/picasa*',
+    },
+    'media_router': {
+      'filepath': 'chrome/browser/media/router/*' \
+                  '|chrome/app/theme/*/common/media_router*' \
+                  '|chrome/browser/resources/media_router/' \
+                  '|chrome/browser/ui/webui/media_router/' \
+                  '|chrome/test/media_router/',
+    },
+    'message_loop': {
+      'filepath': 'base/message_'
+    },
+    'metrics': {
+      'filepath': 'base/metrics/'\
+                  '|chrome/browser/metrics/'\
+                  '|chrome/common/metrics/'\
+                  '|chrome/browser/chromeos/external_metrics'\
+                  '|chrome/browser/extensions/api/metrics_private/'\
+                  '|chrome/browser/ui/webui/metrics_handler'\
+                  '|content/browser/user_metrics.cc'\
+                  '|components/rappor/'\
+                  '|content/public/browser/user_metrics.h'\
+                  # Exclude XML files; in particular, histograms.xml.
+                  '|tools/metrics/[^.]*([.](?!xml$).*)?$',
+    },
+    'metrics_xml_files': {
+      # Subscribe to this to watch for changes to histograms.xml.
+      'filepath': 'tools/metrics/.*\.xml$',
+    },
+    'midi': {
+      'filepath': 'midi',
+    },
+    'mojo': {
+      'filepath': 'mojo',
+    },
+    'mouse_lock': {
+      'filepath': 'mouse_lock',
+    },
+    'nacl': {
+      'filepath': 'chrome/nacl/|chrome/test/nacl/|'\
+        'chrome/browser/nacl_host/|chrome/common/nacl|'\
+        'native_client_sdk/src/doc/',
+    },
+    'native_client_sdk': {
+      'filepath': '^native_client_sdk/',
+    },
+    'navigation': {
+      'filepath': 'content/browser/frame_host|'\
+                  'content/browser/renderer_host/render_process_host.*|'\
+                  'content/browser/renderer_host/render_view_host.*|'\
+                  'content/browser/web_contents/web_contents_impl.*|'\
+                  'content/renderer/render_frame.*|'\
+                  'content/renderer/render_view.*'
+    },
+    'net': {
+      'filepath': 'net/',
+    },
+    'net_error_list': {
+      'filepath': 'net/base/net_error_list.h',
+    },
+    'net_log': {
+      'filepath': 'net/base/net_log|' \
+        'chrome/browser/net/.*net_log|' \
+        'chrome/browser/net/passive_log_collector|' \
+        'chrome/browser/resources/net_internals/|' \
+        'chrome/browser/ui/webui/net_internals/'
+    },
+    'netinfo': {
+      'filepath': 'netinfo',
+    },
+    'network_quality': {
+      'filepath': 'net/base/network_quality*',
+    },
+    'notifications': {
+      'filepath': 'chrome/browser/extensions/api/notifications/|' \
+        'chrome/browser/notifications/|' \
+        'chrome/test/data/notifications/|' \
+        'content/browser/notifications/|' \
+        'content/child/notifications/|' \
+        'content/common/platform_notification|' \
+        'content/public/browser/platform_notification|' \
+        'content/public/common/platform_notification|' \
+        'content/renderer/notification_|' \
+        'ui/message_center/'
+    },
+    'npapi_headers': {
+      'filepath': 'third_party/npapi/bindings/',
+    },
+    'ntp': {
+      'filepath': 'chrome/browser/resources/ntp4/|'\
+        'chrome/browser/resources/ntp_android/|'\
+        'chrome/browser/ui/webui/ntp/',
+    },
+    'omnibox': {
+      'filepath': 'chrome/browser/autocomplete/'\
+                  '|chrome/browser/ui/.*/omnibox/'
+    },
+    'options': {
+      'filepath': 'chrome/browser/resources/options/|'\
+          'chrome/browser/ui/webui/options/',
+    },
+    'overview_mode': {
+      'filepath': 'ash/wm/overview/',
+    },
+    'ozone': {
+      'filepath': 'ui/ozone/|'\
+        'ui/events/ozone/|'\
+        'ui/gfx/ozone/|'\
+        'ui/gl/gl_.*egl.*|'\
+        'ui/gl/gl_.*ozone.*'
+    },
+    'panels': {
+      'filepath': 'chrome/browser/ui/panels'\
+                  '|chrome/browser/ui/cocoa/panels'\
+                  '|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',
+    },
+    'permissions': {
+      'filepath': 'content/(child,browser)/permissions/'\
+                  '|content/common/permission_*'\
+                  '|content/public/(common,browser)/permission_*'\
+                  '|chrome/browser/permissions/'\
+                  '|chrome/browser/content_settings/permission*'\
+                  '|permission_context',
+    },
+    'plugin': {
+      'filepath': 'chrome/browser/plugin|chrome/plugin/|'\
+        'chrome/common/plugin',
+    },
+    'polymer': {
+      'filepath': 'third_party/polymer/|'\
+                  'ui/webui/resources/polymer_resources.grdp',
+    },
+    'precache': {
+      'filepath': '[pP]recache'
+    },
+    'predictors': {
+      'filepath': 'predictors',
+    },
+    'prepopulated_engines': {
+      'filepath': 'components/search_engines/prepopulated_engines.json',
+    },
+    'prerender': {
+      'filepath': 'prerender'
+    },
+    'push_messaging': {
+      'filepath': 'push_messaging'
+    },
+    'pyauto': {
+      'filepath': 'chrome/test/pyautolib' \
+                  '|chrome/test/functional' \
+                  '|chrome/browser/automation/automation_provider_json'
+    },
+    'remoting': {
+      'filepath': 'remoting/' \
+                  '|testing/chromoting'
+    },
+    'rlz_id': {
+      'filepath' :'rlz/lib/machine_id.cc|'\
+                  'rlz/lib/machine_id.h|'\
+                  'rlz/win/lib/machine_id_win.cc',
+    },
+    'safe_browsing': {
+      'filepath': 'chrome/(browser|common|renderer)/safe_browsing/',
+    },
+    'sandbox': {
+      'filepath': 'sandbox/'\
+                  '|content/browser/bootstrap_sandbox_mac'\
+                  '|content/browser/renderer_host/render_sandbox_host_linux'\
+                  '|content/browser/renderer_host/sandbox_ipc_linux'\
+                  '|content/browser/zygote_host/'\
+                  '|content/common/sandbox_'\
+                  '|content/zygote/'\
+    },
+    'scheduler': {
+      'filepath': 'cc/scheduler'\
+                  '|components/scheduler'\
+                  '|content/renderer/scheduler'
+    },
+    'screen_orientation': {
+      'filepath': 'screen_orientation',
+    },
+    'search': {
+      'filepath': 'chrome/browser/ui/search/',
+    },
+    'service_worker': {
+      'filepath': 'content/(browser|renderer|child|common)/service_worker/',
+    },
+    'site_instance': {
+      'filepath': 'content/browser/site_instance|'\
+        'content/browser/browsing_instance',
+    },
+    'speech': {
+      'filepath': 'chrome/browser/speech/'\
+                  '|content/browser/speech/'\
+                  '|content/common/.*speech'\
+                  '|content/public/.*speech'
+    },
+    'spellcheck': {
+      'filepath': 'chrome/browser/spellchecker/'\
+                   '|chrome/browser/tab_contents/spellchecker'\
+                   '|chrome/browser/tab_contents/spelling_menu'\
+                   '|chrome/common/spellcheck_'\
+                   '|chrome/renderer/spellchecker/'\
+                   '|third_party/hunspell/'\
+                   '|third_party/hunspell_dictionaries/'\
+    },
+    'streams': {
+      'filepath': 'content/browser/streams/',
+    },
+    'supervised_users': {
+      'filepath': 'chrome/browser/.*managed_mode'\
+                  '|chrome/browser/.*managed_user'\
+                  '|chrome/browser/.*supervised_user',
+    },
+    'sync': {
+      'filepath': 'chrome/browser/sync/|sync/|components/sync_driver/',
+    },
+    'syncfs': {
+      'filepath': 'sync_file_system',
+    },
+    'sync_proto': {
+      'filepath': 'sync/protocol/',
+    },
+    'tab_capture': {
+      'filepath': 'cc/output/copy_output_request'\
+        '|chrome/browser/extensions/api/tab_capture/'\
+        '|chrome/test/data/extensions/api_test/tab_capture/'\
+        '|content/browser/compositor/delegated_frame_host'\
+        '|content/browser/media/capture/'\
+        '|content/browser/renderer_host/compositing_iosurface'\
+        '|content/browser/renderer_host/media/(audio_'\
+            '|media_stream_manager|video_)'\
+        '|media/audio/(audio_output_controller|fake_audio_|virtual_audio_)'\
+        '|media/base/video_frame\.h'\
+        '|media/video/capture/video_capture_',
+    },
+    'tab_contents': {
+      'filepath': 'chrome/browser/tab_contents/|'\
+        'content/browser/tab_contents/|'\
+        'chrome/browser/ui/tab_contents/',
+    },
+    'tab_media_indicators': {
+      'filepath': 'chrome/browser/media/audio_stream_monitor'\
+        '|chrome/browser/ui/cocoa/tabs/tab_controller\.mm'\
+        '|chrome/browser/ui/tabs/tab_utils'\
+        '|chrome/browser/ui/views/tabs/tab\.cc'\
+        '|chrome/browser/ui/views/tabs/tab_renderer_data'\
+        '|media/audio/audio_(output_controller|power_monitor)',
+    },
+    'task_manager': {
+      'filepath': 'task_manager'
+    },
+    'tcmalloc': {
+      'filepath': 'third_party/tcmalloc'
+    },
+    'telemetry': {
+      'filepath': 'tools/perf/|'\
+                  'tools/telemetry/'
+    },
+    'tests': {
+      'filepath': 'apitest|unittest|browsertest|uitest|chrome/test/',
+    },
+    'textinput': {
+      'filepath': 'content/browser/renderer_host/gtk_im'\
+                  '|content/browser/renderer_host/gtk_key'\
+                  '|content/browser/renderer_host/render_widget_host_view'\
+                  '|content/browser/renderer_host/text_input'\
+                  '|ui/base/ime/'\
+                  '|ui/base/gtk/event'\
+                  '|ui/base/gtk/gtk_im'\
+                  '|ui/base/keycodes/'\
+                  '|ui/base/win/ime'\
+                  '|ui/views/controls/textfield/'\
+                  '|ui/views/ime/'
+    },
+    'textinput_chromeos': {
+      'filepath': 'chrome/browser/chromeos/input_method/'\
+                  '|chrome/browser/chromeos/extensions/input_method'\
+                  '|chrome/browser/chromeos/status/input_method'\
+                  '|chrome/browser/extensions/extension_input_'\
+                  '|chrome/browser/resources/keyboard'\
+                  '|chrome/browser/resources/options/language'\
+                  '|chrome/browser/ui/webui/options/'\
+                  'chromeos/.*(language|keyboard)'\
+                  '|chrome/browser/ui/webui/options/language'\
+                  '|chromeos/ime/*'
+    },
+    'timers': {
+      'filepath': 'base/timer/'\
+                  '|components/timers/'
+    },
+    'tools': {
+      'filepath': 'tools/',
+    },
+    'tools_emacs': {
+      'filepath': 'tools/emacs/',
+    },
+    'tracing': {
+      'filepath': 'base/debug/trace_event.*'\
+                  '|base/trace_event/'\
+                  '|content/browser/tracing/'\
+                  '|components/tracing/'
+    },
+    'ui_compositor': {
+      'filepath': 'ui/compositor/layer\.|'\
+                  'ui/compositor/layer_unittest|'\
+                  'ui/compositor/compositor',
+    },
+    'ui_resources': {
+      'filepath': 'ui/resources/'\
+                  '|ui/base/native_theme/resources/'\
+                  '|chrome/app/theme/'
+    },
+    'valgrind': {
+      'filepath': 'valgrind',
+    },
+    'version_assembly': {
+      'filepath': 'chrome/app/version_assembly',
+    },
+    'views': {
+      # Applies to all files and subdirs within this directory.
+      'filepath': '^ui/views/',
+    },
+    'views_core': {
+      'filepath': 'ui/views/view.h|'\
+                  'ui/views/view.cc|'\
+                  'ui/views/widget/',
+    },
+    'views_corewm': {
+      'filepath': 'ui/views/corewm/',
+    },
+    'virtual_keyboard': {
+      'filepath': 'ui/keyboard/'\
+                  'chrome/test/data/chromeos/virtual_keyboard/'\
+                  'chrome/common/extensions/api/virtual_keyboard',
+    },
+    'webrtc_media': {
+      'filepath': 'chrome/browser/media/|'\
+                  'content/browser/renderer_host/media/|'\
+                  'content/common/gpu/media/|'\
+                  'content/renderer/media/|'\
+                  'media/base/android/|'\
+                  'media/capture/|'\
+                  'video.*_accelerat',
+    },
+    'webrtc_browser_tests': {
+      'filepath': 'chrome/browser/media/.*webrtc.*browsertest|'\
+                  'content/browser/media/.*webrtc.*browsertest',
+    },
+    'website_settings': {
+      'filepath': 'chrome/browser/content_settings/'\
+                  '|chrome/browser/ui/views/website_settings/'\
+                  '|chrome/browser/ui/website_settings/'\
+                  '|chrome/common/content_settings'\
+                  '|components/content_settings/',
+    },
+    'windows_sandboxing': {
+      'filepath': 'sandbox/win/',
+    },
+    'x11': {
+      'filepath': 'content/browser/renderer_host/backing_store_x\.' \
+                  '|chrome/browser/chromeos/input_method/xkeyboard\.' \
+                  '|chrome/browser/chromeos/system_key_event_listener\.' \
+                  '|chrome/browser/chromeos/'\
+                  'xinput_hierarchy_changed_event_listener\.' \
+                  '|chrome/browser/chromeos/wm_' \
+                  '|ui/base/x/'
+    },
+    'zoom': {
+      'filepath': 'chrome/browser/ui/zoom/' \
+                  '|components/ui/zoom/' \
+                  '|content/browser/host_zoom_*' \
+                  '|content/browser/storage_partition_impl*' \
+                  '|content/public/browser/host_zoom_map.h' \
+                  '|content/public/browser/storage_partition.h'
+    },
+  },
+
+  'WATCHLISTS': {
+    'accelerator_table': ['mazda+watch@chromium.org',
+                          'derat+watch@chromium.org',
+                          'yusukes+watch@chromium.org'],
+    'accessibility': ['aboxhall+watch@chromium.org',
+                      'dmazzoni+watch@chromium.org',
+                      'dtseng+watch@chromium.org',
+                      'je_julie.kim@chromium.org',
+                      'nektar+watch@chromium.org',
+                      'plundblad+watch@chromium.org',
+                      'yuzo+watch@chromium.org'],
+    'activity_log': ['felt@chromium.org'],
+    'android_infra': ['yfriedman+watch@chromium.org',
+                      'klundberg+watch@chromium.org',
+                      'jbudorick+watch@chromium.org'],
+    'android_media': ['avayvod+watch@chromium.org',
+                      'mlamouri+watch-media@chromium.org'],
+    'android_tab': ['avayvod+watch@chromium.org', 'dtrainor@chromium.org'],
+    'android_webview': ['android-webview-reviews@chromium.org'],
+    'app_list': ['tfarina@chromium.org',
+                 'mgiuca@chromium.org',
+                 'tapted@chromium.org'],
+    'app_shortcuts': ['mgiuca@chromium.org', 'tapted@chromium.org'],
+    'appcache': ['michaeln@chromium.org'],
+    'apps': ['tfarina@chromium.org', 'chromium-apps-reviews@chromium.org'],
+    'ash': ['sadrul@chromium.org',
+            'kalyan.kondapally@intel.com'],
+    'aura': ['sadrul@chromium.org',
+             'kalyan.kondapally@intel.com'],
+    'aura_compositor': ['danakj+watch@chromium.org',
+                        'jbauman+watch@chromium.org',
+                        'piman+watch@chromium.org',
+                        'sievers+watch@chromium.org',
+                        'kalyan.kondapally@intel.com'],
+    'auto_bisect': ['auto-bisect-reviews@chromium.org'],
+    'autofill': ['bondd+autofillwatch@chromium.org',
+                 'estade+watch@chromium.org',
+                 'jdonnelly+autofillwatch@chromium.org',
+                 'rouslan+autofill@chromium.org'],
+    'automation': ['robertshield@chromium.org'],
+    'background_sync': ['jkarlin+watch@chromium.org'],
+    'base_allocator': ['dmikurube@chromium.org',
+                       'wfh+watch@chromium.org'],
+    'base_memory': ['gavinp+memory@chromium.org'],
+    'base_win': ['grt+watch@chromium.org', 'wfh+watch@chromium.org'],
+    'battery_status': ['timvolodine@chromium.org'],
+    'blimp' : ['dtrainor+watch-blimp@chromium.org',
+               'kmarshall+watch-blimp@chromium.org',
+               'maniscalco+watch-blimp@chromium.org',
+               'nyquist+watch-blimp@chromium.org'],
+    'bookmarks': ['noyau+watch@chromium.org', 'tfarina@chromium.org'],
+    'browser_chromeos': ['davemoore+watch@chromium.org'],
+    'browser_components': ['browser-components-watch@chromium.org'],
+    'browser_compositor': ['vollick@chromium.org',
+                           'piman+watch@chromium.org'],
+    'browser_resources': ['arv+watch@chromium.org'],
+    'browsing_data': ['markusheintz@chromium.org'],
+    'bubble': ['msw+watch@chromium.org',
+               'rouslan+bubble@chromium.org',
+               'hcarmona+bubble@chromium.org',
+               'groby+bubble@chromium.org'],
+    'cache_storage': ['jkarlin+watch@chromium.org', 'nhiroki@chromium.org'],
+    'cast': ['avayvod+watch@chromium.org',
+             'imcheng+watch@chromium.org',
+             'isheriff+watch@chromium.org',
+             'jasonroberts+watch@google.com',
+             'miu+watch@chromium.org',
+             'xjz+watch@chromium.org'],
+    'cc': ['cc-bugs@chromium.org'],
+    'chrome_elf': ['caitkp+watch@chromium.org',],
+    'chrome_views': ['tfarina@chromium.org'],
+    'chromecast': ['gunsch+watch@chromium.org',
+                   'halliwell+watch@chromium.org',
+                   'lcwu+watch@chromium.org'],
+    'chromedriver': ['samuong+watch@chromium.org'],
+    'chromeos' : ['oshima+watch@chromium.org'],
+    'chromeos_attestation' : ['dkrahn+watch@chromium.org'],
+    'chromeos_calculator' : ['dharcourt@chromium.org'],
+    'chromeos_dbus': ['hashimoto+watch@chromium.org'],
+    'chromeos_net' : ['stevenjb+watch@chromium.org'],
+    'chromeos_power' : ['derat+watch@chromium.org'],
+    'chromeos_login' : ['achuith+watch@chromium.org',
+                        'dzhioev+watch@chromium.org'],
+    'clang_update': ['ukai+watch@chromium.org',
+                     'dmikurube+clang@chromium.org',
+                     'eugenis+clang@chromium.org',
+                     'glider+clang@chromium.org'],
+    'clipboard': ['dcheng@chromium.org'],
+    'closure': ['dbeam+watch-closure@chromium.org',
+                'vitalyp+closure@chromium.org',
+                'jlklein+watch-closure@chromium.org'],
+    'components_deps': ['blundell+watchlist@chromium.org',
+                        'droger+watchlist@chromium.org',
+                        'sdefresne+watchlist@chromium.org'],
+    'content': ['jam@chromium.org',
+                'darin-cc@chromium.org' ],
+    'content_bluetooth': ['scheib+watch@chromium.org'],
+    'content_input': ['jdduke+watch@chromium.org'],
+    'content_renderer': [ 'mkwst+moarreviews-renderer@chromium.org',
+                          'mlamouri+watch-content@chromium.org'],
+    'content_shell': ['jochen+watch@chromium.org',
+                      'mkwst+moarreviews-shell@chromium.org',
+                      'mlamouri+watch-content@chromium.org'],
+    'content_worker': ['blink-worker-reviews@chromium.org',
+                       'kinuko+watch@chromium.org'],
+    'custom_handlers': ['vabr+watchlist@chromium.org'],
+    'deep_memory_profiler': ['dmikurube@chromium.org'],
+    'device_bluetooth': ['scheib+watch@chromium.org'],
+    'device_sensors': ['timvolodine@chromium.org',
+                       'mvanouwerkerk@chromium.org',
+                       'rijubrata.bhaumik@intel.com',
+                       'mlamouri+watch-sensors@chromium.org'],
+    'developer_recommended_flags': ['scheib+watch@chromium.org'],
+    'devtools': ['pfeldman@chromium.org', 'yurys@chromium.org',
+                 'devtools-reviews@chromium.org'],
+    'disk_cache': ['gavinp+disk@chromium.org'],
+    'dns': ['mmenke@chromium.org'],
+    'download_database': ['benjhayden+dwatch@chromium.org'],
+    'download': ['benjhayden+dwatch@chromium.org', 'asanka@chromium.org'],
+    'downloads_ext': ['benjhayden+dwatch@chromium.org'],
+    'downloads_ui': ['asanka@chromium.org', 'benjhayden+dwatch@chromium.org'],
+    'drive': ['tfarina@chromium.org'],
+    'drive_resource_metadata': ['hashimoto+watch@chromium.org'],
+    'eme': ['eme-reviews@chromium.org'],
+    'enhanced_bookmarks': ['noyau+watch@chromium.org'],
+    'events': ['tdresser+watch@chromium.org', 'jdduke+watch@chromium.org'],
+    'extension': ['chromium-apps-reviews@chromium.org',
+                  'extensions-reviews@chromium.org'],
+    'fileapi': ['kinuko+fileapi@chromium.org',
+                'nhiroki@chromium.org',
+                'tzik@chromium.org'],
+    'filebrowse': ['rginda+watch@chromium.org'],
+    'filesapp': ['mtomasz+watch@chromium.org'],
+    'ftp': ['phajdan.jr@chromium.org'],
+    'gcm': ['zea+watch@chromium.org'],
+    'geolocation': ['mvanouwerkerk@chromium.org',
+                    'mlamouri+watch-geolocation@chromium.org'],
+    'gfx_geometry': ['cc-bugs@chromium.org'],
+    'gfx_image': ['rsesek+watch@chromium.org'],
+    'gn': ['tfarina@chromium.org'],
+    'gpu': ['piman+watch@chromium.org'],
+    'history_ui': ['dubroy@chromium.org', 'pam+watch@chromium.org'],
+    'hotword': ['rlp+watch@chromium.org'],
+    'i18n': ['jshin+watch@chromium.org'],
+    'importer': ['tfarina@chromium.org'],
+    'indexed_db': ['cmumford@chromium.org',
+                   'dgrogan@chromium.org', 'jsbell+idb@chromium.org'],
+    'installer': ['grt+watch@chromium.org', 'wfh+watch@chromium.org'],
+    'installer_linux': [ 'mmoss@chromium.org'],
+    'instant': ['dcblack@chromium.org', 'jered@chromium.org',
+                'samarth+watch@chromium.org', 'donnd+watch@chromium.org',
+                'melevin+watch@chromium.org', 'dougw+watch@chromium.org',
+                'kmadhusu+watch@chromium.org', 'dhollowa+watch@chromium.org',
+                'jfweitz+watch@chromium.org', 'skanuj+watch@chromium.org'],
+    'ios_chrome': ['sdefresne+watch@chromium.org'],
+    'ipc': ['jam@chromium.org', 'darin-cc@chromium.org'],
+    'libwebp': ['urvang@chromium.org', 'jzern@chromium.org',
+                'skal@google.com', 'vikasa@google.com'],
+    'libvpx': ['tomfinegan@chromium.org', 'jzern@chromium.org',
+               'fgalligan@chromium.org', 'johannkoenig@chromium.org'],
+    'linux_fonts': ['derat+watch@chromium.org'],
+    'linux_sandboxing': ['jln+watch@chromium.org'],
+    'linux_seccomp_bpf': ['jln+watch@chromium.org'],
+    'supervised_users': ['pam+watch@chromium.org'],
+    'mandoline': ['yzshen+watch@chromium.org',
+                  'penghuang+watch-mandoline@chromium.org'],
+    'manifest': ['mlamouri+watch-manifest@chromium.org'],
+    'md_settings': ['dbeam+watch-settings@chromium.org',
+                    'jhawkins+watch-md-settings@chromium.org',
+                    'jlklein+watch-md-settings@chromium.org',
+                    'michaelpg+watch-md-settings@chromium.org',
+                    'stevenjb+watch-md-settings@chromium.org'],
+    'media': ['feature-media-reviews@chromium.org'],
+    'media_galleries': ['thestig@chromium.org', 'tommycli@chromium.org'],
+    'media_router': ['media-router+watch@chromium.org'],
+    'message_loop': ['sadrul@chromium.org'],
+    'metrics': ['asvitkine+watch@chromium.org'],
+    'metrics_xml_files': ['asvitkine+watch@chromium.org'],
+    'midi': ['toyoshim+midi@chromium.org'],
+    'mojo': ['aa@chromium.org',
+             'abarth@chromium.org',
+             'ben+mojo@chromium.org',
+             'darin@chromium.org',
+             'qsr+mojo@chromium.org',
+             'viettrungluu+watch@chromium.org',
+             'yzshen+watch@chromium.org'],
+    'mouse_lock': ['scheib+watch@chromium.org'],
+    'nacl': ['native-client-reviews@googlegroups.com'],
+    'native_client_sdk': ['sbc@chromium.org', 'binji+watch@chromium.org'],
+    'navigation': ['creis+watch@chromium.org', 'nasko+codewatch@chromium.org'],
+    'net': ['cbentzel+watch@chromium.org'],
+    'net_error_list': ['mmenke@chromium.org'],
+    'netinfo': ['jkarlin+watch@chromium.org'],
+    'net_log': ['mmenke@chromium.org', 'eroman@chromium.org'],
+    'network_quality': ['rdsmith@chromium.org'],
+    'notifications': ['peter+watch@chromium.org',
+                      'mlamouri+watch-notifications@chromium.org'],
+    'npapi_headers': ['stuartmorgan@chromium.org'],
+    'ntp': ['dbeam+watch-ntp@chromium.org',
+            'pedrosimonetti+watch@chromium.org'],
+    'omnibox': ['suzhe@chromium.org'],
+    'options': ['dbeam+watch-options@chromium.org',
+                'michaelpg+watch-options@chromium.org'],
+    'overview_mode': ['tdanderson+overview@chromium.org'],
+    'ozone': ['kalyan.kondapally@intel.com', 'ozone-reviews@chromium.org'],
+    'panels': ['dimich@chromium.org', 'jennb@chromium.org',
+               'dcheng@chromium.org', 'jianli@chromium.org'],
+    'password_manager': ['mkwst+watchlist-passwords@chromium.org',
+                         'gcasto+watchlist@chromium.org',
+                         'vabr+watchlist@chromium.org'],
+    'pepper_api': ['bradnelson+warch@chromium.org',
+                   'piman+watch@chromium.org', 'ihf+watch@chromium.org',
+                   'yusukes+watch@chromium.org', 'binji+watch@chromium.org',
+                   'teravest+watch@chromium.org', 'tzik@chromium.org'],
+    'permissions': ['mlamouri+watch-permissions@chromium.org'],
+    'plugin': ['jam@chromium.org'],
+    'polymer': ['michaelpg+watch-polymer@chromium.org'],
+    'precache': ['wifiprefetch-reviews@google.com'],
+    'predictors': ['shishir+watch@chromium.org'],
+    'prepopulated_engines': ['vasilii+watch@chromium.org'],
+    'prerender': ['cbentzel+watch@chromium.org', 'tburkard+watch@chromium.org',
+                  'gavinp+prer@chromium.org', 'davidben+watch@chromium.org'],
+    'push_messaging': ['peter+watch@chromium.org', 'johnme+watch@chromium.org',
+                       'mvanouwerkerk+watch@chromium.org'],
+    'pyauto': ['anantha@chromium.org',
+               'dyu@chromium.org',
+               'dennisjeffrey@chromium.org'],
+    'remoting': ['chromoting-reviews@chromium.org'],
+    'rlz_id': ['gab+watch@chromium.org',
+               'robertshield+watch@chromium.org'],
+    'safe_browsing': ['grt+watch@chromium.org'],
+    'sandbox': ['rickyz+watch@chromium.org'],
+    'scheduler': ['scheduler-bugs@chromium.org'],
+    'screen_orientation': ['mlamouri+watch-screen-orientation@chromium.org'],
+    'service_worker': ['tzik@chromium.org',
+                       'kinuko+serviceworker@chromium.org',
+                       'nhiroki@chromium.org',
+                       'horo+watch@chromium.org',
+                       'jsbell+serviceworker@chromium.org',
+                       'michaeln@chromium.org',
+                       'serviceworker-reviews@chromium.org'],
+    'site_instance': ['creis+watch@chromium.org', 'ajwong+watch@chromium.org',
+                      'nasko+codewatch@chromium.org'],
+    'spellcheck': ['groby+spellwatch@chromium.org',
+                   'rlp+watch@chromium.org',
+                   'rouslan+spell@chromium.org'],
+    'streams': ['zork+watch@chromium.org'],
+    'sync': ['tim+watch@chromium.org',
+             'maxbogue+watch@chromium.org',
+             'plaree+watch@chromium.org',
+             'pvalenzuela+watch@chromium.org',
+             'zea+watch@chromium.org'],
+    'syncfs': ['kinuko+fileapi@chromium.org',
+               'nhiroki@chromium.org',
+               'tzik@chromium.org'],
+    'sync_proto': ['albertb+watch@chromium.org'],
+    'tab_capture': ['miu+watch@chromium.org'],
+    'tab_contents': ['avi@chromium.org',
+                     'creis+watch@chromium.org', 'ajwong+watch@chromium.org'],
+    'tab_media_indicators': ['miu+watch@chromium.org'],
+    'tcmalloc': ['dmikurube@chromium.org'],
+    'telemetry': ['telemetry-reviews@chromium.org'],
+    'tests': [],
+    'textinput': ['suzhe@chromium.org',
+                  'yusukes+watch@chromium.org',
+                  'nona+watch@chromium.org',
+                  'shuchen+watch@chromium.org'],
+    'textinput_chromeos': ['yusukes+watch@chromium.org',
+                           'nona+watch@chromium.org',
+                           'shuchen+watch@chromium.org'],
+    'timers': ['chirantan+watch@chromium.org'],
+    'tools_emacs': ['dhollowa+watch@chromium.org'],
+    'tracing': ['tracing+reviews@chromium.org', 'wfh+watch@chromium.org'],
+    'ui_compositor': ['cc-bugs@chromium.org'],
+    'ui_resources': ['oshima+watch@chromium.org'],
+    'valgrind': ['bruening+watch@chromium.org',
+                 'glider+watch@chromium.org'],
+    'version_assembly': ['caitkp+watch@chromium.org',
+                         'gab+watch@chromium.org'],
+    'views': ['tfarina@chromium.org'],
+    'views_core': ['tdanderson+views@chromium.org'],
+    'virtual_keyboard': ['dfaden+virtualkb@google.com',
+                         'groby+virtualkb@chromium.org'],
+    'webrtc_media': ['mcasas+watch@chromium.org',
+                     'posciak+watch@chromium.org'],
+    'webrtc_browser_tests': ['phoglund+watch@chromium.org',
+                             'tnakamura+watch@chromium.org'],
+    'website_settings': ['markusheintz@chromium.org',
+                         'raymes+watch@chromium.org'],
+    'windows_sandboxing': ['wfh+watch@chromium.org'],
+    'x11': ['derat+watch@chromium.org',
+            'sadrul@chromium.org',
+            'yusukes+watch@chromium.org'],
+    'zoom': ['wjmaclean@chromium.org'],
+  },
+}
diff --git a/android_webview/DEPS b/android_webview/DEPS
new file mode 100644
index 0000000..d45fa05
--- /dev/null
+++ b/android_webview/DEPS
@@ -0,0 +1,22 @@
+# Please include torne@ and (erikwright@) on the review for any changes
+# to DEPS files under android_webview/
+
+# Do not add any includes under chrome/ anywhere in android_webview.
+
+include_rules = [
+  # lib is the top-level target, and must remain a leaf in the dependency tree.
+  "-android_webview/lib",
+
+  "+components/data_reduction_proxy",
+  "+components/devtools_discovery",
+  "+content/public/common",
+  "+crypto",
+  "+gpu",
+  "+jni",
+  "+net",
+  "+skia",
+  "+third_party/skia/include",
+  "+ui/android",
+  "+ui/base",
+  "+ui/gfx",
+]
diff --git a/android_webview/OWNERS b/android_webview/OWNERS
new file mode 100644
index 0000000..ec9174a
--- /dev/null
+++ b/android_webview/OWNERS
@@ -0,0 +1,5 @@
+boliu@chromium.org
+michaelbai@chromium.org
+mnaganov@chromium.org
+sgurun@chromium.org
+torne@chromium.org
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp
new file mode 100644
index 0000000..9a390f9
--- /dev/null
+++ b/android_webview/android_webview.gyp
@@ -0,0 +1,431 @@
+# Copyright 2009 The Chromium 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': {
+    'chromium_code': 1,
+  },
+  'targets': [
+    {
+      'target_name': 'android_webview_pak',
+      'type': 'none',
+      'dependencies': [
+        '<(DEPTH)/content/app/resources/content_resources.gyp:content_resources',
+        '<(DEPTH)/net/net.gyp:net_resources',
+        '<(DEPTH)/third_party/WebKit/public/blink_resources.gyp:blink_resources',
+        '<(DEPTH)/ui/resources/ui_resources.gyp:ui_resources',
+      ],
+      'variables': {
+        'conditions': [
+          ['target_arch=="arm" or target_arch=="ia32" or target_arch=="mipsel"', {
+            'arch_suffix':'32'
+          }],
+          ['target_arch=="arm64" or target_arch=="x64" or target_arch=="mips64el"', {
+            'arch_suffix':'64'
+          }],
+        ],
+        'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/android_webview',
+      },
+      'actions': [
+        {
+          'action_name': 'generate_aw_resources',
+          'variables': {
+            'grit_grd_file': 'ui/aw_resources.grd',
+          },
+          'includes': [ '../build/grit_action.gypi' ],
+        },
+        {
+          'action_name': 'repack_android_webview_pack',
+          'variables': {
+            'pak_inputs': [
+              '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_resources.pak',
+              '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_image_resources_100_percent.pak',
+              '<(SHARED_INTERMEDIATE_DIR)/content/app/resources/content_resources_100_percent.pak',
+              '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.pak',
+              '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.pak',
+              '<(SHARED_INTERMEDIATE_DIR)/ui/resources/ui_resources_100_percent.pak',
+              '<(grit_out_dir)/aw_resources.pak',
+            ],
+            'pak_output': '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak',
+          },
+         'includes': [ '../build/repack_action.gypi' ],
+        },
+        {
+          'action_name': 'generate_aw_strings',
+          'variables': {
+            'grit_grd_file': 'ui/aw_strings.grd',
+          },
+          'includes': [ '../build/grit_action.gypi' ],
+        },
+        {
+          'action_name': 'android_webview_repack_locales',
+          'variables': {
+            'repack_locales': 'tools/webview_repack_locales.py',
+          },
+          'inputs': [
+            '<(repack_locales)',
+            '<!@pymod_do_main(webview_repack_locales -i -p <(PRODUCT_DIR) -s <(SHARED_INTERMEDIATE_DIR) <(locales))'
+          ],
+          'outputs': [
+            '<!@pymod_do_main(webview_repack_locales -o -p <(PRODUCT_DIR) -s <(SHARED_INTERMEDIATE_DIR) <(locales))'
+          ],
+          'action': [
+            'python',
+            '<(repack_locales)',
+            '-p', '<(PRODUCT_DIR)',
+            '-s', '<(SHARED_INTERMEDIATE_DIR)',
+            '<@(locales)',
+          ],
+        },
+        {
+          'action_name': 'rename_snapshot_blob',
+          'inputs': [
+            '<(PRODUCT_DIR)/snapshot_blob.bin',
+          ],
+          'outputs': [
+            '<(PRODUCT_DIR)/snapshot_blob_<(arch_suffix).bin',
+          ],
+          'action': [
+            'python',
+            '<(DEPTH)/build/cp.py',
+            '<@(_inputs)',
+            '<@(_outputs)',
+          ],
+        },
+        {
+          'action_name': 'rename_natives_blob',
+          'inputs': [
+            '<(PRODUCT_DIR)/natives_blob.bin',
+          ],
+          'outputs': [
+            '<(PRODUCT_DIR)/natives_blob_<(arch_suffix).bin',
+          ],
+          'action': [
+            'python',
+            '<(DEPTH)/build/cp.py',
+            '<@(_inputs)',
+            '<@(_outputs)',
+          ],
+        },
+      ],
+    },
+    {
+      'target_name': 'android_webview_locale_paks',
+      'type': 'none',
+      'variables': {
+        'locale_pak_files': [ '<@(webview_locales_input_paks)' ],
+      },
+      'includes': [
+        'apk/system_webview_locales_paks.gypi',
+        '../build/android/locale_pak_resources.gypi',
+      ],
+    },
+    {
+      'target_name': 'android_webview_strings_grd',
+      'android_unmangled_name': 1,
+      'type': 'none',
+      'variables': {
+        'grd_file': '../android_webview/java/strings/android_webview_strings.grd',
+      },
+      'includes': [
+          '../build/java_strings_grd.gypi',
+      ],
+    },
+    {
+      'target_name': 'android_webview_version',
+      'type': 'none',
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '<(SHARED_INTERMEDIATE_DIR)',
+        ],
+      },
+      # Because generate_version generates a header, we must set the
+      # hard_dependency flag.
+      'hard_dependency': 1,
+      'actions': [
+        {
+          'action_name': 'generate_version',
+          'includes': [
+            '../build/util/version.gypi',
+          ],
+          'variables': {
+            'template_input_path': 'common/aw_version_info_values.h.version',
+          },
+          'inputs': [
+            '<(version_py_path)',
+            '<(template_input_path)',
+            '<(version_path)',
+            '<(lastchange_path)',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/android_webview/common/aw_version_info_values.h',
+          ],
+          'action': [
+            'python',
+            '<(version_py_path)',
+            '-f', '<(version_path)',
+            '-f', '<(lastchange_path)',
+            '<(template_input_path)',
+            '<@(_outputs)',
+          ],
+          'message': 'Generating version information',
+        },
+      ],
+    },
+    {
+      'target_name': 'android_webview_common',
+      'type': 'static_library',
+      'dependencies': [
+        '../android_webview/native/webview_native.gyp:webview_native',
+        '../cc/cc.gyp:cc_surfaces',
+        '../components/components.gyp:auto_login_parser',
+        '../components/components.gyp:autofill_content_renderer',
+        '../components/components.gyp:breakpad_host',
+        '../components/components.gyp:cdm_browser',
+        '../components/components.gyp:cdm_renderer',
+        '../components/components.gyp:crash_component',
+        '../components/components.gyp:data_reduction_proxy_core_browser',
+        '../components/components.gyp:devtools_discovery',
+        '../components/components.gyp:navigation_interception',
+        '../components/components.gyp:printing_common',
+        '../components/components.gyp:printing_browser',
+        '../components/components.gyp:printing_renderer',
+        '../components/components.gyp:visitedlink_browser',
+        '../components/components.gyp:visitedlink_renderer',
+        '../components/components.gyp:web_contents_delegate_android',
+        '../content/content.gyp:content_app_both',
+        '../content/content.gyp:content_browser',
+        '../gin/gin.gyp:gin',
+        '../gpu/blink/gpu_blink.gyp:gpu_blink',
+        '../gpu/command_buffer/command_buffer.gyp:gles2_utils',
+        '../gpu/gpu.gyp:command_buffer_service',
+        '../gpu/gpu.gyp:gl_in_process_context',
+        '../gpu/gpu.gyp:gles2_c_lib',
+        '../gpu/gpu.gyp:gles2_implementation',
+        '../gpu/skia_bindings/skia_bindings.gyp:gpu_skia_bindings',
+        '../media/media.gyp:media',
+        '../media/midi/midi.gyp:midi',
+        '../printing/printing.gyp:printing',
+        '../skia/skia.gyp:skia',
+        '../third_party/WebKit/public/blink.gyp:blink',
+        '../ui/events/events.gyp:gesture_detection',
+        '../ui/gl/gl.gyp:gl',
+        '../ui/shell_dialogs/shell_dialogs.gyp:shell_dialogs',
+        '../v8/tools/gyp/v8.gyp:v8',
+        'android_webview_pak',
+        'android_webview_version',
+        '../components/components.gyp:policy',
+        '../components/components.gyp:policy_component',
+        '../components/components.gyp:pref_registry',
+        '../components/url_formatter/url_formatter.gyp:url_formatter',
+      ],
+      'include_dirs': [
+        '..',
+        '../skia/config',
+        '<(SHARED_INTERMEDIATE_DIR)/ui/resources/',
+      ],
+      'sources': [
+        'browser/aw_browser_context.cc',
+        'browser/aw_browser_context.h',
+        'browser/aw_browser_main_parts.cc',
+        'browser/aw_browser_main_parts.h',
+        'browser/aw_browser_permission_request_delegate.h',
+        'browser/aw_browser_policy_connector.cc',
+        'browser/aw_browser_policy_connector.h',
+        'browser/aw_contents_client_bridge_base.cc',
+        'browser/aw_contents_client_bridge_base.h',
+        'browser/aw_content_browser_client.cc',
+        'browser/aw_content_browser_client.h',
+        'browser/aw_contents_io_thread_client.h',
+        'browser/aw_cookie_access_policy.cc',
+        'browser/aw_cookie_access_policy.h',
+        'browser/aw_dev_tools_discovery_provider.cc',
+        'browser/aw_dev_tools_discovery_provider.h',
+        'browser/aw_download_manager_delegate.cc',
+        'browser/aw_download_manager_delegate.h',
+        'browser/aw_form_database_service.cc',
+        'browser/aw_form_database_service.h',
+        'browser/aw_gl_surface.cc',
+        'browser/aw_gl_surface.h',
+        'browser/aw_http_auth_handler_base.cc',
+        'browser/aw_http_auth_handler_base.h',
+        'browser/aw_javascript_dialog_manager.cc',
+        'browser/aw_javascript_dialog_manager.h',
+        'browser/aw_locale_manager.h',
+        'browser/aw_login_delegate.cc',
+        'browser/aw_login_delegate.h',
+        'browser/aw_media_client_android.cc',
+        'browser/aw_media_client_android.h',
+        'browser/aw_message_port_message_filter.cc',
+        'browser/aw_message_port_message_filter.h',
+        'browser/aw_message_port_service.h',
+        'browser/aw_permission_manager.cc',
+        'browser/aw_permission_manager.h',
+        'browser/aw_pref_store.cc',
+        'browser/aw_pref_store.h',
+        'browser/aw_print_manager.cc',
+        'browser/aw_print_manager.h',
+        'browser/aw_printing_message_filter.cc',
+        'browser/aw_printing_message_filter.h',
+        'browser/aw_quota_manager_bridge.cc',
+        'browser/aw_quota_manager_bridge.h',
+        'browser/aw_quota_permission_context.cc',
+        'browser/aw_quota_permission_context.h',
+        'browser/aw_render_thread_context_provider.cc',
+        'browser/aw_render_thread_context_provider.h',
+        'browser/aw_request_interceptor.cc',
+        'browser/aw_request_interceptor.h',
+        'browser/aw_resource_context.cc',
+        'browser/aw_resource_context.h',
+        'browser/aw_ssl_host_state_delegate.cc',
+        'browser/aw_ssl_host_state_delegate.h',
+        'browser/aw_result_codes.h',
+        'browser/aw_web_preferences_populater.cc',
+        'browser/aw_web_preferences_populater.h',
+        'browser/aw_web_resource_response.cc',
+        'browser/aw_web_resource_response.h',
+        'browser/browser_view_renderer.cc',
+        'browser/browser_view_renderer.h',
+        'browser/browser_view_renderer_client.h',
+        'browser/child_frame.cc',
+        'browser/child_frame.h',
+        'browser/deferred_gpu_command_service.cc',
+        'browser/deferred_gpu_command_service.h',
+        'browser/find_helper.cc',
+        'browser/find_helper.h',
+        'browser/hardware_renderer.cc',
+        'browser/hardware_renderer.h',
+        'browser/icon_helper.cc',
+        'browser/icon_helper.h',
+        'browser/input_stream.h',
+        'browser/jni_dependency_factory.h',
+        'browser/gl_view_renderer_manager.cc',
+        'browser/gl_view_renderer_manager.h',
+        'browser/net/android_stream_reader_url_request_job.cc',
+        'browser/net/android_stream_reader_url_request_job.h',
+        'browser/net/aw_http_user_agent_settings.h',
+        'browser/net/aw_http_user_agent_settings.cc',
+        'browser/net/aw_network_delegate.cc',
+        'browser/net/aw_network_delegate.h',
+        'browser/net/aw_url_request_context_getter.cc',
+        'browser/net/aw_url_request_context_getter.h',
+        'browser/net/aw_url_request_job_factory.cc',
+        'browser/net/aw_url_request_job_factory.h',
+        'browser/net_disk_cache_remover.cc',
+        'browser/net_disk_cache_remover.h',
+        'browser/net/init_native_callback.h',
+        'browser/net/input_stream_reader.cc',
+        'browser/net/input_stream_reader.h',
+        'browser/parent_compositor_draw_constraints.cc',
+        'browser/parent_compositor_draw_constraints.h',
+        'browser/parent_output_surface.cc',
+        'browser/parent_output_surface.h',
+        'browser/renderer_host/aw_render_view_host_ext.cc',
+        'browser/renderer_host/aw_render_view_host_ext.h',
+        'browser/renderer_host/aw_resource_dispatcher_host_delegate.cc',
+        'browser/renderer_host/aw_resource_dispatcher_host_delegate.h',
+        'browser/scoped_allow_wait_for_legacy_web_view_api.h',
+        'browser/scoped_app_gl_state_restore.cc',
+        'browser/scoped_app_gl_state_restore.h',
+        'browser/shared_renderer_state.cc',
+        'browser/shared_renderer_state.h',
+        'common/android_webview_message_generator.cc',
+        'common/android_webview_message_generator.h',
+        'common/aw_content_client.cc',
+        'common/aw_content_client.h',
+        'common/aw_descriptors.h',
+        'common/aw_hit_test_data.cc',
+        'common/aw_hit_test_data.h',
+        'common/aw_message_port_messages.h',
+        'common/aw_resource.h',
+        'common/aw_switches.cc',
+        'common/aw_switches.h',
+        'common/devtools_instrumentation.h',
+        'common/render_view_messages.cc',
+        'common/render_view_messages.h',
+        'common/url_constants.cc',
+        'common/url_constants.h',
+        'crash_reporter/aw_microdump_crash_reporter.cc',
+        'crash_reporter/aw_microdump_crash_reporter.h',
+        'lib/aw_browser_dependency_factory_impl.cc',
+        'lib/aw_browser_dependency_factory_impl.h',
+        'lib/main/aw_main_delegate.cc',
+        'lib/main/aw_main_delegate.h',
+        'lib/main/webview_jni_onload.cc',
+        'lib/main/webview_jni_onload.h',
+        'public/browser/draw_gl.h',
+        'renderer/aw_content_renderer_client.cc',
+        'renderer/aw_content_renderer_client.h',
+        'renderer/aw_content_settings_client.cc',
+        'renderer/aw_content_settings_client.h',
+        'renderer/aw_key_systems.cc',
+        'renderer/aw_key_systems.h',
+        'renderer/aw_message_port_client.cc',
+        'renderer/aw_message_port_client.h',
+        'renderer/aw_print_web_view_helper_delegate.cc',
+        'renderer/aw_print_web_view_helper_delegate.h',
+        'renderer/aw_render_process_observer.cc',
+        'renderer/aw_render_process_observer.h',
+        'renderer/aw_render_frame_ext.cc',
+        'renderer/aw_render_frame_ext.h',
+        'renderer/aw_render_view_ext.cc',
+        'renderer/aw_render_view_ext.h',
+        'renderer/print_render_frame_observer.cc',
+        'renderer/print_render_frame_observer.h',
+      ],
+    },
+    {
+      'target_name': 'libwebviewchromium',
+      'includes': [
+          'libwebviewchromium.gypi',
+      ],
+    },
+    {
+      'target_name': 'android_webview_java',
+      'type': 'none',
+      'dependencies': [
+        '../android_webview/native/webview_native.gyp:android_webview_aw_permission_request_resource',
+        '../components/components.gyp:external_video_surface_java',
+        '../components/components.gyp:navigation_interception_java',
+        '../components/components.gyp:policy_java',
+        '../components/components.gyp:web_contents_delegate_android_java',
+        '../content/content.gyp:content_java',
+        '../ui/android/ui_android.gyp:ui_java',
+        'android_webview_locale_paks',
+        'android_webview_strings_grd',
+      ],
+      'variables': {
+        'java_in_dir': '../android_webview/java',
+        'has_java_resources': 1,
+        'R_package': 'org.chromium.android_webview',
+        'R_package_relpath': 'org/chromium/android_webview',
+        'android_manifest_path': '../android_webview/apk/java/AndroidManifest.xml', # for lint
+      },
+      'includes': [ '../build/java.gypi' ],
+    },
+    {
+      'target_name': 'system_webview_glue_java',
+      'variables': {
+        'android_sdk_jar': '../third_party/android_platform/webview/frameworks_6.0.jar',
+        'java_in_dir': 'glue/java',
+      },
+      'includes': [ 'apk/system_webview_glue_common.gypi' ],
+    },
+    {
+      'target_name': 'system_webview_apk',
+      'dependencies': [
+        'system_webview_glue_java',
+      ],
+      'variables': {
+        'apk_name': 'SystemWebView',
+        'android_sdk_jar': '../third_party/android_platform/webview/frameworks_6.0.jar',
+        'java_in_dir': '../build/android/empty',
+        'resource_dir': 'apk/java/res',
+      },
+      'includes': [ 'apk/system_webview_apk_common.gypi' ],
+    },
+  ],
+  'includes': [
+    'android_webview_tests.gypi',
+  ],
+}
diff --git a/android_webview/android_webview_shell.gyp b/android_webview/android_webview_shell.gyp
new file mode 100644
index 0000000..a5d898f
--- /dev/null
+++ b/android_webview/android_webview_shell.gyp
@@ -0,0 +1,27 @@
+# Copyright 2015 The Chromium 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': 'android_webview_shell_apk',
+      'type': 'none',
+      'dependencies': [
+        '../base/base.gyp:base_java_test_support',
+      ],
+      'variables': {
+        'apk_name': 'AndroidWebViewShell',
+        'java_in_dir': 'tools/WebViewShell',
+        'resource_dir': 'tools/WebViewShell/res',
+        'is_test_apk': 1,
+        'test_type': 'instrumentation',
+        'isolate_file': 'android_webview_shell_test_apk.isolate',
+        'android_manifest_path': 'tools/WebViewShell/AndroidManifest.xml', # for lint
+      },
+      'includes': [
+        '../build/java_apk.gypi',
+        '../build/android/test_runner.gypi',
+      ],
+    },
+  ],
+}
diff --git a/android_webview/android_webview_shell_test_apk.isolate b/android_webview/android_webview_shell_test_apk.isolate
new file mode 100644
index 0000000..85e85d3
--- /dev/null
+++ b/android_webview/android_webview_shell_test_apk.isolate
@@ -0,0 +1,19 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'conditions': [
+    ['OS=="android"', {
+      'variables': {
+        'files': [
+          '<(DEPTH)/android_webview/tools/WebViewShell/test/',
+          '<(DEPTH)/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt',
+          '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/global-interface-listing.html',
+          '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt',
+          '<(DEPTH)/third_party/WebKit/LayoutTests/webexposed/resources/global-interface-listing.js',
+        ],
+      },
+    }],
+  ],
+}
\ No newline at end of file
diff --git a/android_webview/android_webview_test_apk.isolate b/android_webview/android_webview_test_apk.isolate
new file mode 100644
index 0000000..7436aca
--- /dev/null
+++ b/android_webview/android_webview_test_apk.isolate
@@ -0,0 +1,14 @@
+# 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.
+{
+  'conditions': [
+    ['OS=="android"', {
+      'variables': {
+        'files': [
+          '<(DEPTH)/android_webview/test/data/',
+        ],
+      },
+    }],
+  ],
+}
diff --git a/android_webview/android_webview_tests.gypi b/android_webview/android_webview_tests.gypi
new file mode 100644
index 0000000..cd6d738
--- /dev/null
+++ b/android_webview/android_webview_tests.gypi
@@ -0,0 +1,227 @@
+# 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.
+{
+  'targets': [
+    {
+      'target_name': 'android_webview_apk',
+      'type': 'none',
+      'dependencies': [
+        'libstandalonelibwebviewchromium',
+        'android_webview_java',
+        'android_webview_pak',
+        'libdrawgl',
+      ],
+      'variables': {
+        'apk_name': 'AndroidWebView',
+        'java_in_dir': 'test/shell',
+        'native_lib_target': 'libstandalonelibwebviewchromium',
+        'native_lib_version_name': '<(version_full)',
+        'resource_dir': 'test/shell/res',
+        'extensions_to_not_compress': '.lpak,.pak,.dat,.bin',
+        'asset_location': '<(PRODUCT_DIR)/android_webview_apk/assets',
+        'extra_native_libs': ['<(SHARED_LIB_DIR)/libdrawgl.>(android_product_extension)'],
+        'snapshot_copy_files': '<(snapshot_copy_files)',
+        'additional_input_paths': [
+          '<(asset_location)/webviewchromium.pak',
+          '<(asset_location)/asset_file.html',
+          '<(asset_location)/cookie_test.html',
+          '<(asset_location)/asset_icon.png',
+          '<(asset_location)/full_screen_video.js',
+          '<(asset_location)/full_screen_video_test.html',
+          '<(asset_location)/full_screen_video_inside_div_test.html',
+          '<(asset_location)/multiple_videos_test.html',
+          '<(asset_location)/video.mp4',
+          '<(asset_location)/visual_state_during_fullscreen_test.html',
+          '<(asset_location)/visual_state_waits_for_js_test.html',
+          '<(asset_location)/visual_state_on_page_commit_visible_test.html',
+          '<@(snapshot_additional_input_paths)',
+        ],
+        'conditions': [
+          ['icu_use_data_file_flag==1', {
+            'additional_input_paths': [
+              '<(asset_location)/icudtl.dat',
+            ],
+          }],
+        ],
+        'includes': [ 'snapshot_copying.gypi' ],
+      },
+      'copies': [
+        {
+          'destination': '<(asset_location)',
+          'files': [
+            '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak',
+            '<(java_in_dir)/assets/asset_file.html',
+            '<(java_in_dir)/assets/asset_icon.png',
+            '<(java_in_dir)/assets/cookie_test.html',
+            '<(java_in_dir)/assets/full_screen_video.js',
+            '<(java_in_dir)/assets/full_screen_video_test.html',
+            '<(java_in_dir)/assets/full_screen_video_inside_div_test.html',
+            '<(java_in_dir)/assets/multiple_videos_test.html',
+            '<(java_in_dir)/assets/video.mp4',
+            '<(java_in_dir)/assets/visual_state_during_fullscreen_test.html',
+            '<(java_in_dir)/assets/visual_state_waits_for_js_test.html',
+            '<(java_in_dir)/assets/visual_state_on_page_commit_visible_test.html',
+            '<@(snapshot_copy_files)',
+          ],
+          'conditions': [
+            ['icu_use_data_file_flag==1', {
+              'files': [
+                '<(PRODUCT_DIR)/icudtl.dat',
+              ],
+            }],
+          ],
+        },
+      ],
+      'includes': [
+        '../build/java_apk.gypi',
+        '../build/util/version.gypi',
+      ],
+    },
+    {
+      # android_webview_apk creates a .jar as a side effect. Any java
+      # targets that need that .jar in their classpath should depend on this
+      # target. For more details see the content_shell_apk_java target.
+      'target_name': 'android_webview_apk_java',
+      'type': 'none',
+      'dependencies': [
+        'android_webview_apk',
+      ],
+      'includes': [ '../build/apk_fake_jar.gypi' ],
+    },
+    {
+      'target_name': 'android_webview_test_apk',
+      'type': 'none',
+      'dependencies': [
+        '../base/base.gyp:base_java_test_support',
+        '../content/content_shell_and_tests.gyp:content_java_test_support',
+        '../net/net.gyp:net_java_test_support',
+        '../testing/android/on_device_instrumentation.gyp:broker_java',
+        '../testing/android/on_device_instrumentation.gyp:require_driver_apk',
+        'android_webview_apk_java',
+      ],
+      'variables': {
+        'apk_name': 'AndroidWebViewTest',
+        'java_in_dir': '../android_webview/javatests',
+        'is_test_apk': 1,
+        'test_type': 'instrumentation',
+        'isolate_file': 'android_webview_test_apk.isolate',
+      },
+      'includes': [
+        '../build/java_apk.gypi',
+        '../build/android/test_runner.gypi',
+      ],
+    },
+    {
+      'target_name': 'android_webview_unittests',
+      'type': '<(gtest_target_type)',
+      'dependencies': [
+        '../base/base.gyp:test_support_base',
+        '../content/content_shell_and_tests.gyp:test_support_content',
+        '../net/net.gyp:net_test_support',
+        '../testing/android/native_test.gyp:native_test_native_code',
+        '../testing/gmock.gyp:gmock',
+        '../testing/gtest.gyp:gtest',
+        '../ui/base/ui_base.gyp:ui_base_jni_headers',
+        '../ui/gl/gl.gyp:gl',
+        '../ui/gl/gl.gyp:gl_test_support',
+        'android_webview_common',
+        'android_webview_unittests_jni',
+      ],
+      'include_dirs': [
+        '..',
+        '../skia/config',
+        '<(SHARED_INTERMEDIATE_DIR)/android_webview_unittests',
+      ],
+      'sources': [
+        'browser/aw_static_cookie_policy_unittest.cc',
+        'browser/aw_form_database_service_unittest.cc',
+        'browser/browser_view_renderer_unittest.cc',
+        'browser/net/android_stream_reader_url_request_job_unittest.cc',
+        'browser/net/input_stream_reader_unittest.cc',
+        'browser/test/fake_window.cc',
+        'browser/test/fake_window.h',
+        'browser/test/rendering_test.cc',
+        'browser/test/rendering_test.h',
+        'lib/main/webview_tests.cc',
+        'native/aw_contents_client_bridge_unittest.cc',
+        'native/aw_media_url_interceptor_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',
+      ],
+    },
+    {
+      'target_name': 'android_webview_unittest_java',
+      'type': 'none',
+      'dependencies': [
+        '../base/base.gyp:base_java_test_support',
+        '../content/content_shell_and_tests.gyp:content_java_test_support',
+        'android_webview_java',
+      ],
+      'variables': {
+        'java_in_dir': '../android_webview/unittestjava',
+      },
+      'includes': [ '../build/java.gypi' ],
+    },
+    {
+      'target_name': 'android_webview_unittests_jni',
+      'type': 'none',
+      'sources': [
+          '../android_webview/unittestjava/src/org/chromium/android_webview/unittest/InputStreamUnittest.java',
+          '../android_webview/unittestjava/src/org/chromium/android_webview/unittest/MockAwContentsClientBridge.java',
+      ],
+      'variables': {
+        'jni_gen_package': 'android_webview_unittests',
+      },
+      'includes': [ '../build/jni_generator.gypi' ],
+    },
+    {
+      'target_name': 'android_webview_unittests_apk',
+      'type': 'none',
+      'dependencies': [
+        'android_webview_unittest_java',
+        'android_webview_unittests',
+      ],
+      'variables': {
+        'test_suite_name': 'android_webview_unittests',
+        'additional_input_paths': [
+          '<(PRODUCT_DIR)/android_webview_unittests_apk/assets/asset_file.ogg',
+        ],
+      },
+      'copies': [
+        {
+          'destination': '<(PRODUCT_DIR)/android_webview_unittests_apk/assets',
+          'files': [
+            'test/unittest/assets/asset_file.ogg',
+          ],
+        },
+      ],
+      'includes': [ '../build/apk_test.gypi' ],
+    },
+    {
+      'target_name': 'libdrawgl',
+      'type': 'shared_library',
+      # Do not depend on any other component here, since this target
+      # builds a separate shared library!
+      'include_dirs': [
+        '..',
+      ],
+      'variables': {
+        # This library uses native JNI exports; tell gyp so that the required
+        # symbols will be kept.
+        'use_native_jni_exports': 1,
+      },
+      'sources': [
+          '../android_webview/test/shell/src/draw_gl/draw_gl.cc',
+      ],
+    },
+    {
+      'target_name': 'libstandalonelibwebviewchromium',
+      'includes': [
+        'libwebviewchromium.gypi',
+      ],
+    },
+  ],
+}
diff --git a/android_webview/apk/java/AndroidManifest.xml b/android_webview/apk/java/AndroidManifest.xml
new file mode 100644
index 0000000..3e979a6
--- /dev/null
+++ b/android_webview/apk/java/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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 xmlns:android="http://schemas.android.com/apk/res/android"
+    package="{{package|default('com.android.webview')}}">
+    <uses-sdk android:minSdkVersion="{{minsdk|default(21)}}"
+              android:targetSdkVersion="{{targetsdk|default(23)}}">
+    </uses-sdk>
+
+    <uses-feature android:name="android.hardware.touchscreen"
+            android:required="false"/>
+
+    <application android:label="Android System WebView"
+        android:icon="@drawable/icon_webview"
+        android:multiArch="true">
+        <activity android:name="com.android.webview.chromium.LicenseActivity"
+                  android:label="@string/license_activity_title"
+                  >
+            <intent-filter>
+                <action android:name="android.settings.WEBVIEW_LICENSE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+                       android:value="true" />
+        </activity>
+        <provider android:name="com.android.webview.chromium.LicenseContentProvider"
+                  android:exported="true"
+                  android:authorities="{{package|default('com.android.webview')}}.LicenseContentProvider" />
+        <meta-data android:name="com.android.webview.WebViewLibrary"
+                   android:value="libwebviewchromium.so" />
+    </application>
+</manifest>
diff --git a/android_webview/apk/java/proguard.flags b/android_webview/apk/java/proguard.flags
new file mode 100644
index 0000000..8dbce53
--- /dev/null
+++ b/android_webview/apk/java/proguard.flags
@@ -0,0 +1,94 @@
+# Don't rename anything, it makes stack traces unintelligible. We only allow the
+# obfuscation pass to run so that we can discard attributes like local variable
+# tables.
+-keepnames class *** { *; }
+
+# Keep source file and line number information for stack traces.
+-keepattributes SourceFile,LineNumberTable
+
+# Keep all runtime visible annotations.
+-keepattributes RuntimeVisibleAnnotations
+
+# Disable optimization as this causes proguard to remove seemingly random stuff,
+# including things explicitly kept in this configuration.
+-dontoptimize
+
+# Keep the factory and its public members; it's the main entry point used by the
+# framework.
+-keep class com.android.webview.chromium.WebViewChromiumFactoryProvider {
+    public *;
+}
+
+# Keep JNI interfaces.
+-keepclasseswithmembers class com.android.webview.chromium.**,org.chromium.** {
+  @**.AccessedByNative <fields>;
+}
+-keepclasseswithmembers class com.android.webview.chromium.**,org.chromium.** {
+  @**.CalledByNative <methods>;
+}
+-keepclasseswithmembers class com.android.webview.chromium.**,org.chromium.** {
+  @**.CalledByNativeUnchecked <methods>;
+}
+-keepclasseswithmembers class com.android.webview.chromium.**,org.chromium.** {
+  native <methods>;
+}
+
+# Keep things explicitly marked as used by reflection
+-keepclasseswithmembers class com.android.webview.chromium.**,org.chromium.** {
+  @**.UsedByReflection *;
+}
+
+# Linker dynamically casts to $TestRunner when running tests. We don't run these
+# tests in WebView.
+-dontnote org.chromium.base.library_loader.Linker$TestRunner
+
+# Don't note about the API 21 compatibility code which references various
+# hidden APIs via reflection.
+-dontnote com.android.webview.chromium.WebViewDelegateFactory$Api21CompatibilityDelegate
+
+# DefaultAndroidKeyStore uses reflection to access internal OpenSSL state.
+-dontnote org.chromium.net.DefaultAndroidKeyStore
+
+# MediaPlayerBridge uses reflection to access internal metadata.
+-dontnote org.chromium.media.MediaPlayerBridge
+
+# ProxyChangeListener$ProxyReceiver uses reflection to access internal
+# android.net.ProxyProperties.
+-dontnote org.chromium.net.ProxyChangeListener$ProxyReceiver
+
+# Silence warnings about reflection used to check for onShow/HideCustomView.
+# This class is not really kept since it's in a library jar.
+-keep class android.webkit.WebChromeClient {
+  void onShowCustomView(...);
+  void onHideCustomView();
+}
+
+# Accessed via reflection but not present in all builds
+-keep class com.android.webview.chromium.Drp {
+  public java.lang.String KEY;
+}
+-dontnote com.android.webview.chromium.Drp
+
+# Keep framework support for SmartClip.
+-keep class com.android.webview.chromium.WebViewChromium {
+  public void extractSmartClipData(int,int,int,int);
+  public void setSmartClipResultHandler(android.os.Handler);
+}
+
+# Ignore notes and warnings about the support library, which uses reflection and
+# may reference classes no longer in the SDK.
+-dontnote android.support.**
+-dontwarn android.support.**
+
+# Keep all enum values and valueOf methods. See
+# http://proguard.sourceforge.net/index.html#manual/examples.html
+# for the reason for this. Also, see http://crbug.com/248037.
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+# Remove when ViewStructure is no longer duplicated (crbug.com/513229)
+-dontwarn android.view.*
+-dontwarn android.app.assist.*
+-dontwarn android.webkit.*
diff --git a/android_webview/apk/java/res/drawable-hdpi/icon_webview.png b/android_webview/apk/java/res/drawable-hdpi/icon_webview.png
new file mode 100644
index 0000000..4f9377f
--- /dev/null
+++ b/android_webview/apk/java/res/drawable-hdpi/icon_webview.png
Binary files differ
diff --git a/android_webview/apk/java/res/drawable-mdpi/icon_webview.png b/android_webview/apk/java/res/drawable-mdpi/icon_webview.png
new file mode 100644
index 0000000..9bc6817c
--- /dev/null
+++ b/android_webview/apk/java/res/drawable-mdpi/icon_webview.png
Binary files differ
diff --git a/android_webview/apk/java/res/drawable-xhdpi/icon_webview.png b/android_webview/apk/java/res/drawable-xhdpi/icon_webview.png
new file mode 100644
index 0000000..9412fbe
--- /dev/null
+++ b/android_webview/apk/java/res/drawable-xhdpi/icon_webview.png
Binary files differ
diff --git a/android_webview/apk/java/res/drawable-xxhdpi/icon_webview.png b/android_webview/apk/java/res/drawable-xxhdpi/icon_webview.png
new file mode 100644
index 0000000..bd8c447
--- /dev/null
+++ b/android_webview/apk/java/res/drawable-xxhdpi/icon_webview.png
Binary files differ
diff --git a/android_webview/apk/system_webview_apk_common.gypi b/android_webview/apk/system_webview_apk_common.gypi
new file mode 100644
index 0000000..2ccb878
--- /dev/null
+++ b/android_webview/apk/system_webview_apk_common.gypi
@@ -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.
+#
+# When making changes remember that this is shared with the internal .apk
+# build rules.
+{
+  'type': 'none',
+  'dependencies': [
+    '<(DEPTH)/android_webview/android_webview.gyp:libwebviewchromium',
+  ],
+  'variables': {
+    'native_lib_target': 'libwebviewchromium',
+    'native_lib_version_name': '<(version_full)',
+    'never_lint': 1,
+    'shared_resources': 1,
+    'extensions_to_not_compress': '.lpak,.pak,.bin,.dat',
+    'asset_location': '<(INTERMEDIATE_DIR)/assets/',
+    'snapshot_copy_files': '<(snapshot_copy_files)',
+    'jinja_inputs': ['<(android_manifest_template_path)'],
+    'jinja_output': '<(INTERMEDIATE_DIR)/AndroidManifest.xml',
+    'jinja_variables': [ '<@(android_manifest_template_vars)' ],
+    'android_manifest_template_vars': [ ],
+    'android_manifest_template_path': '<(DEPTH)/android_webview/apk/java/AndroidManifest.xml',
+    'android_manifest_path': '<(jinja_output)',
+    'proguard_enabled': 'true',
+    'proguard_flags_paths': ['<(DEPTH)/android_webview/apk/java/proguard.flags'],
+    # TODO: crbug.com/405035 Find a better solution for WebView .pak files.
+    'additional_input_paths': [
+      '<(asset_location)/webviewchromium.pak',
+      '<(asset_location)/webview_licenses.notice',
+      '<@(snapshot_additional_input_paths)',
+    ],
+    'includes': [
+      '../../build/util/version.gypi',
+      '../snapshot_copying.gypi',
+    ],
+    'conditions': [
+      ['icu_use_data_file_flag==1', {
+        'additional_input_paths': [
+          '<(asset_location)/icudtl.dat',
+        ],
+      }],
+    ],
+  },
+  'copies': [
+    {
+      'destination': '<(asset_location)',
+      'files': [
+        '<(PRODUCT_DIR)/android_webview_assets/webviewchromium.pak',
+        '<@(snapshot_copy_files)',
+      ],
+      'conditions': [
+        ['icu_use_data_file_flag==1', {
+          'files': [
+            '<(PRODUCT_DIR)/icudtl.dat',
+          ],
+        }],
+      ],
+    },
+  ],
+  'actions': [
+    {
+      'action_name': 'generate_webview_license_notice',
+      'inputs': [
+        '<!@(python <(DEPTH)/android_webview/tools/webview_licenses.py notice_deps)',
+        '<(DEPTH)/android_webview/tools/licenses_notice.tmpl',
+        '<(DEPTH)/android_webview/tools/webview_licenses.py',
+      ],
+      'outputs': [
+        '<(asset_location)/webview_licenses.notice',
+      ],
+      'action': [
+        'python',
+        '<(DEPTH)/android_webview/tools/webview_licenses.py',
+        'notice',
+        '<(asset_location)/webview_licenses.notice',
+      ],
+      'message': 'Generating WebView license notice',
+    },
+  ],
+  'includes': [
+    '../../build/java_apk.gypi',
+    '../../build/android/jinja_template.gypi',
+  ],
+}
diff --git a/android_webview/apk/system_webview_glue_common.gypi b/android_webview/apk/system_webview_glue_common.gypi
new file mode 100644
index 0000000..9b15be4
--- /dev/null
+++ b/android_webview/apk/system_webview_glue_common.gypi
@@ -0,0 +1,42 @@
+# Copyright 2015 The Chromium 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 is shared between system_webview_glue_java and system_webview_glue_next_java
+{
+  'type': 'none',
+  'dependencies': [
+    '<(DEPTH)/android_webview/android_webview.gyp:android_webview_java',
+    '<(DEPTH)/android_webview/android_webview.gyp:android_webview_pak',
+  ],
+  'variables': {
+    'never_lint': 1,
+    'resource_rewriter_package': 'com.android.webview.chromium',
+    'resource_rewriter_dir': '<(intermediate_dir)/resource_rewriter',
+    'resource_rewriter_path': '<(resource_rewriter_dir)/com/android/webview/chromium/ResourceRewriter.java',
+    'additional_input_paths': ['<(resource_rewriter_path)'],
+    'generated_src_dirs': ['<(resource_rewriter_dir)'],
+  },
+  'actions': [
+    # Generate ResourceRewriter.java
+    {
+      'action_name': 'generate_resource_rewriter',
+      'message': 'generate ResourceRewriter for <(_target_name)',
+      'inputs':[
+        '<(DEPTH)/build/android/gyp/util/build_utils.py',
+        '<(DEPTH)/build/android/gyp/generate_resource_rewriter.py',
+        '>@(dependencies_res_zip_paths)',
+      ],
+      'outputs': [
+        '<(resource_rewriter_path)',
+      ],
+      'action': [
+        'python', '<(DEPTH)/build/android/gyp/generate_resource_rewriter.py',
+        '--package-name', '<(resource_rewriter_package)',
+        '--dep-packages', '>(additional_res_packages)',
+        '--output-dir', '<(resource_rewriter_dir)',
+      ],
+    },
+  ],
+  'includes': [ '../../build/java.gypi' ],
+}
diff --git a/android_webview/apk/system_webview_locales_paks.gypi b/android_webview/apk/system_webview_locales_paks.gypi
new file mode 100644
index 0000000..110dde5
--- /dev/null
+++ b/android_webview/apk/system_webview_locales_paks.gypi
@@ -0,0 +1,69 @@
+# Copyright (c) 2015 The Chromium 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 set of locales that should be packed inside the
+# System WebView apk.
+# TODO: consider unifying this list with the one in chrome_android_paks.gypi
+# once Chrome includes all the locales that the WebView needs.
+{
+  'variables': {
+    'webview_locales_input_paks_folder': '<(PRODUCT_DIR)/android_webview_assets/locales/',
+    'webview_locales_input_paks': [
+      '<(webview_locales_input_paks_folder)/am.pak',
+      '<(webview_locales_input_paks_folder)/ar.pak',
+      '<(webview_locales_input_paks_folder)/bg.pak',
+      '<(webview_locales_input_paks_folder)/bn.pak',
+      '<(webview_locales_input_paks_folder)/ca.pak',
+      '<(webview_locales_input_paks_folder)/cs.pak',
+      '<(webview_locales_input_paks_folder)/da.pak',
+      '<(webview_locales_input_paks_folder)/de.pak',
+      '<(webview_locales_input_paks_folder)/el.pak',
+      '<(webview_locales_input_paks_folder)/en-GB.pak',
+      '<(webview_locales_input_paks_folder)/en-US.pak',
+      '<(webview_locales_input_paks_folder)/es.pak',
+      '<(webview_locales_input_paks_folder)/es-419.pak',
+      '<(webview_locales_input_paks_folder)/et.pak',
+      '<(webview_locales_input_paks_folder)/fa.pak',
+      '<(webview_locales_input_paks_folder)/fi.pak',
+      '<(webview_locales_input_paks_folder)/fil.pak',
+      '<(webview_locales_input_paks_folder)/fr.pak',
+      '<(webview_locales_input_paks_folder)/gu.pak',
+      '<(webview_locales_input_paks_folder)/he.pak',
+      '<(webview_locales_input_paks_folder)/hi.pak',
+      '<(webview_locales_input_paks_folder)/hr.pak',
+      '<(webview_locales_input_paks_folder)/hu.pak',
+      '<(webview_locales_input_paks_folder)/id.pak',
+      '<(webview_locales_input_paks_folder)/it.pak',
+      '<(webview_locales_input_paks_folder)/ja.pak',
+      '<(webview_locales_input_paks_folder)/kn.pak',
+      '<(webview_locales_input_paks_folder)/ko.pak',
+      '<(webview_locales_input_paks_folder)/lt.pak',
+      '<(webview_locales_input_paks_folder)/lv.pak',
+      '<(webview_locales_input_paks_folder)/ml.pak',
+      '<(webview_locales_input_paks_folder)/mr.pak',
+      '<(webview_locales_input_paks_folder)/ms.pak',
+      '<(webview_locales_input_paks_folder)/nb.pak',
+      '<(webview_locales_input_paks_folder)/nl.pak',
+      '<(webview_locales_input_paks_folder)/pl.pak',
+      '<(webview_locales_input_paks_folder)/pt-BR.pak',
+      '<(webview_locales_input_paks_folder)/pt-PT.pak',
+      '<(webview_locales_input_paks_folder)/ro.pak',
+      '<(webview_locales_input_paks_folder)/ru.pak',
+      '<(webview_locales_input_paks_folder)/sk.pak',
+      '<(webview_locales_input_paks_folder)/sl.pak',
+      '<(webview_locales_input_paks_folder)/sr.pak',
+      '<(webview_locales_input_paks_folder)/sv.pak',
+      '<(webview_locales_input_paks_folder)/sw.pak',
+      '<(webview_locales_input_paks_folder)/ta.pak',
+      '<(webview_locales_input_paks_folder)/te.pak',
+      '<(webview_locales_input_paks_folder)/th.pak',
+      '<(webview_locales_input_paks_folder)/tr.pak',
+      '<(webview_locales_input_paks_folder)/uk.pak',
+      '<(webview_locales_input_paks_folder)/vi.pak',
+      '<(webview_locales_input_paks_folder)/zh-CN.pak',
+      '<(webview_locales_input_paks_folder)/zh-TW.pak',
+    ],
+  },
+}
+
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
new file mode 100644
index 0000000..a6fb034
--- /dev/null
+++ b/android_webview/browser/DEPS
@@ -0,0 +1,48 @@
+include_rules = [
+  "-android_webview",
+  "+android_webview/browser",
+  "+android_webview/common",
+  "+android_webview/native/public",
+  "+android_webview/public/browser",
+
+  "+cc",
+  "-cc/blink",
+
+  "+components/auto_login_parser",
+  "+components/autofill/content/browser",
+  "+components/autofill/core/browser",
+  "+components/autofill/core/common",
+  "+components/cdm/browser",
+  "+components/data_reduction_proxy/core/browser",
+  "+components/navigation_interception",
+  "+components/policy/core/browser",
+  "+components/policy/core/common",
+  "+components/pref_registry",
+  "+components/printing/browser",
+  "+components/printing/common",
+  "+components/url_formatter",
+  "+components/user_prefs",
+  "+components/visitedlink/browser",
+  "+components/webdata/common",
+
+  "+content/public/browser",
+  "+content/public/test",
+
+  "+media/base/android",
+
+  "+policy/policy_constants.h",
+
+  "+printing",
+
+  "+ui/gfx",
+  "+ui/gl",
+
+  # Temporary until we bundle our own favicon. See
+  # AwContentBrowserClient::GetDefaultFavicon
+  "!ui/resources/grit/ui_resources.h",
+
+  # POD structure required by the find-in-page IPC messages.
+  "+third_party/WebKit/public/web/WebFindOptions.h",
+  # Interface required for in-process input event handling.
+  "+third_party/WebKit/public/web/WebCompositorInputHandler.h"
+]
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc
new file mode 100644
index 0000000..713b308
--- /dev/null
+++ b/android_webview/browser/aw_browser_context.cc
@@ -0,0 +1,445 @@
+// 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 "android_webview/browser/aw_browser_context.h"
+
+#include "android_webview/browser/aw_browser_policy_connector.h"
+#include "android_webview/browser/aw_form_database_service.h"
+#include "android_webview/browser/aw_permission_manager.h"
+#include "android_webview/browser/aw_pref_store.h"
+#include "android_webview/browser/aw_quota_manager_bridge.h"
+#include "android_webview/browser/aw_resource_context.h"
+#include "android_webview/browser/jni_dependency_factory.h"
+#include "android_webview/browser/net/aw_url_request_context_getter.h"
+#include "android_webview/browser/net/init_native_callback.h"
+#include "android_webview/common/aw_content_client.h"
+#include "base/base_paths_android.h"
+#include "base/bind.h"
+#include "base/path_service.h"
+#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/core/browser/data_reduction_proxy_compression_stats.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_service.h"
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
+#include "components/data_reduction_proxy/core/browser/data_store.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
+#include "components/policy/core/browser/browser_policy_connector_base.h"
+#include "components/policy/core/browser/configuration_policy_pref_store.h"
+#include "components/policy/core/browser/url_blacklist_manager.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/url_formatter/url_fixer.h"
+#include "components/user_prefs/user_prefs.h"
+#include "components/visitedlink/browser/visitedlink_master.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/ssl_host_state_delegate.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/browser/web_contents.h"
+#include "net/cookies/cookie_store.h"
+#include "net/proxy/proxy_config_service_android.h"
+#include "net/proxy/proxy_service.h"
+
+using base::FilePath;
+using content::BrowserThread;
+
+namespace android_webview {
+
+namespace {
+
+// Shows notifications which correspond to PersistentPrefStore's reading errors.
+void HandleReadError(PersistentPrefStore::PrefReadError error) {
+}
+
+void DeleteDirRecursively(const base::FilePath& path) {
+  if (!base::DeleteFile(path, true)) {
+    // Deleting a non-existent file is considered successful, so this will
+    // trigger only in case of real errors.
+    LOG(WARNING) << "Failed to delete " << path.AsUTF8Unsafe();
+  }
+}
+
+AwBrowserContext* g_browser_context = NULL;
+
+scoped_ptr<net::ProxyConfigService> CreateProxyConfigService() {
+  scoped_ptr<net::ProxyConfigService> config_service =
+      net::ProxyService::CreateSystemProxyConfigService(
+          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+          nullptr /* Ignored on Android */);
+
+  // TODO(csharrison) Architect the wrapper better so we don't need a cast for
+  // android ProxyConfigServices.
+  net::ProxyConfigServiceAndroid* android_config_service =
+      static_cast<net::ProxyConfigServiceAndroid*>(config_service.get());
+  android_config_service->set_exclude_pac_url(true);
+  return config_service.Pass();
+}
+
+bool OverrideBlacklistForURL(const GURL& url, bool* block, int* reason) {
+  // We don't have URLs that should never be blacklisted here.
+  return false;
+}
+
+policy::URLBlacklistManager* CreateURLBlackListManager(
+    PrefService* pref_service) {
+  policy::URLBlacklist::SegmentURLCallback segment_url_callback =
+      static_cast<policy::URLBlacklist::SegmentURLCallback>(
+          url_formatter::SegmentURL);
+  base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
+  scoped_refptr<base::SequencedTaskRunner> background_task_runner =
+      pool->GetSequencedTaskRunner(pool->GetSequenceToken());
+  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
+
+  return new policy::URLBlacklistManager(pref_service, background_task_runner,
+                                         io_task_runner, segment_url_callback,
+                                         base::Bind(OverrideBlacklistForURL));
+}
+
+}  // namespace
+
+// Data reduction proxy is disabled by default.
+bool AwBrowserContext::data_reduction_proxy_enabled_ = false;
+
+// Delete the legacy cache dir (in the app data dir) in 10 seconds after init.
+int AwBrowserContext::legacy_cache_removal_delay_ms_ = 10000;
+
+AwBrowserContext::AwBrowserContext(
+    const FilePath path,
+    JniDependencyFactory* native_factory)
+    : context_storage_path_(path),
+      native_factory_(native_factory) {
+  DCHECK(!g_browser_context);
+  g_browser_context = this;
+
+  // This constructor is entered during the creation of ContentBrowserClient,
+  // before browser threads are created. Therefore any checks to enforce
+  // threading (such as BrowserThread::CurrentlyOn()) will fail here.
+}
+
+AwBrowserContext::~AwBrowserContext() {
+  DCHECK_EQ(this, g_browser_context);
+  g_browser_context = NULL;
+}
+
+// static
+AwBrowserContext* AwBrowserContext::GetDefault() {
+  // TODO(joth): rather than store in a global here, lookup this instance
+  // from the Java-side peer.
+  return g_browser_context;
+}
+
+// static
+AwBrowserContext* AwBrowserContext::FromWebContents(
+    content::WebContents* web_contents) {
+  // This is safe; this is the only implementation of the browser context.
+  return static_cast<AwBrowserContext*>(web_contents->GetBrowserContext());
+}
+
+// static
+void AwBrowserContext::SetDataReductionProxyEnabled(bool enabled) {
+  // Cache the setting value. It is possible that data reduction proxy is
+  // not created yet.
+  data_reduction_proxy_enabled_ = enabled;
+  AwBrowserContext* context = AwBrowserContext::GetDefault();
+  // Can't enable Data reduction proxy if user pref service is not ready.
+  if (context == NULL || context->user_pref_service_.get() == NULL)
+    return;
+  data_reduction_proxy::DataReductionProxySettings* proxy_settings =
+      context->GetDataReductionProxySettings();
+  if (proxy_settings == NULL)
+    return;
+  // At this point, context->PreMainMessageLoopRun() has run, so
+  // context->data_reduction_proxy_io_data() is valid.
+  DCHECK(context->GetDataReductionProxyIOData());
+  context->CreateDataReductionProxyStatisticsIfNecessary();
+  proxy_settings->SetDataReductionProxyEnabled(data_reduction_proxy_enabled_);
+}
+
+// static
+void AwBrowserContext::SetLegacyCacheRemovalDelayForTest(int delay_ms) {
+  legacy_cache_removal_delay_ms_ = delay_ms;
+}
+
+void AwBrowserContext::PreMainMessageLoopRun() {
+  cookie_store_ = CreateCookieStore(this);
+  FilePath cache_path;
+  const FilePath fallback_cache_dir =
+      GetPath().Append(FILE_PATH_LITERAL("Cache"));
+  if (PathService::Get(base::DIR_CACHE, &cache_path)) {
+    cache_path = cache_path.Append(
+        FILE_PATH_LITERAL("org.chromium.android_webview"));
+    // Delay the legacy dir removal to not impact startup performance.
+    BrowserThread::PostDelayedTask(
+        BrowserThread::FILE, FROM_HERE,
+        base::Bind(&DeleteDirRecursively, fallback_cache_dir),
+        base::TimeDelta::FromMilliseconds(legacy_cache_removal_delay_ms_));
+  } else {
+    cache_path = fallback_cache_dir;
+    LOG(WARNING) << "Failed to get cache directory for Android WebView. "
+                 << "Using app data directory as a fallback.";
+  }
+  url_request_context_getter_ = new AwURLRequestContextGetter(
+      cache_path, cookie_store_.get(), CreateProxyConfigService());
+
+  data_reduction_proxy_io_data_.reset(
+      new data_reduction_proxy::DataReductionProxyIOData(
+          data_reduction_proxy::Client::WEBVIEW_ANDROID,
+          data_reduction_proxy::DataReductionProxyParams::kAllowed,
+          url_request_context_getter_->GetNetLog(),
+          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+          false /* enable */,
+          false /* enable_quic */,
+          GetUserAgent()));
+  data_reduction_proxy_settings_.reset(
+      new data_reduction_proxy::DataReductionProxySettings());
+  scoped_ptr<data_reduction_proxy::DataStore> store(
+      new data_reduction_proxy::DataStore());
+  base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
+  scoped_refptr<base::SequencedTaskRunner> db_task_runner =
+      pool->GetSequencedTaskRunnerWithShutdownBehavior(
+          pool->GetSequenceToken(),
+          base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+  data_reduction_proxy_service_.reset(
+      new data_reduction_proxy::DataReductionProxyService(
+          data_reduction_proxy_settings_.get(), nullptr,
+          GetAwURLRequestContext(), store.Pass(),
+          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+          db_task_runner, base::TimeDelta()));
+  data_reduction_proxy_io_data_->SetDataReductionProxyService(
+      data_reduction_proxy_service_->GetWeakPtr());
+
+  visitedlink_master_.reset(
+      new visitedlink::VisitedLinkMaster(this, this, false));
+  visitedlink_master_->Init();
+
+  form_database_service_.reset(
+      new AwFormDatabaseService(context_storage_path_));
+
+  browser_policy_connector_.reset(new AwBrowserPolicyConnector());
+
+  InitUserPrefService();
+
+  // Ensure the storage partition is initialized in time for DataReductionProxy.
+  EnsureResourceContextInitialized(this);
+
+  // TODO(dgn) lazy init, see http://crbug.com/521542
+  data_reduction_proxy_settings_->InitDataReductionProxySettings(
+      user_pref_service_.get(), data_reduction_proxy_io_data_.get(),
+      data_reduction_proxy_service_.Pass());
+  data_reduction_proxy_settings_->MaybeActivateDataReductionProxy(true);
+
+  blacklist_manager_.reset(CreateURLBlackListManager(user_pref_service_.get()));
+}
+
+void AwBrowserContext::AddVisitedURLs(const std::vector<GURL>& urls) {
+  DCHECK(visitedlink_master_);
+  visitedlink_master_->AddURLs(urls);
+}
+
+net::URLRequestContextGetter* AwBrowserContext::CreateRequestContext(
+    content::ProtocolHandlerMap* protocol_handlers,
+    content::URLRequestInterceptorScopedVector request_interceptors) {
+  // This function cannot actually create the request context because
+  // there is a reentrant dependency on GetResourceContext() via
+  // content::StoragePartitionImplMap::Create(). This is not fixable
+  // until http://crbug.com/159193. Until then, assert that the context
+  // has already been allocated and just handle setting the protocol_handlers.
+  DCHECK(url_request_context_getter_.get());
+  url_request_context_getter_->SetHandlersAndInterceptors(
+      protocol_handlers, request_interceptors.Pass());
+  return url_request_context_getter_.get();
+}
+
+net::URLRequestContextGetter*
+AwBrowserContext::CreateRequestContextForStoragePartition(
+    const base::FilePath& partition_path,
+    bool in_memory,
+    content::ProtocolHandlerMap* protocol_handlers,
+    content::URLRequestInterceptorScopedVector request_interceptors) {
+  NOTREACHED();
+  return NULL;
+}
+
+AwQuotaManagerBridge* AwBrowserContext::GetQuotaManagerBridge() {
+  if (!quota_manager_bridge_.get()) {
+    quota_manager_bridge_ = native_factory_->CreateAwQuotaManagerBridge(this);
+  }
+  return quota_manager_bridge_.get();
+}
+
+AwFormDatabaseService* AwBrowserContext::GetFormDatabaseService() {
+  return form_database_service_.get();
+}
+
+data_reduction_proxy::DataReductionProxySettings*
+AwBrowserContext::GetDataReductionProxySettings() {
+  return data_reduction_proxy_settings_.get();
+}
+
+data_reduction_proxy::DataReductionProxyIOData*
+AwBrowserContext::GetDataReductionProxyIOData() {
+  return data_reduction_proxy_io_data_.get();
+}
+
+AwURLRequestContextGetter* AwBrowserContext::GetAwURLRequestContext() {
+  return url_request_context_getter_.get();
+}
+
+AwMessagePortService* AwBrowserContext::GetMessagePortService() {
+  if (!message_port_service_.get()) {
+    message_port_service_.reset(
+        native_factory_->CreateAwMessagePortService());
+  }
+  return message_port_service_.get();
+}
+
+// Create user pref service for autofill functionality.
+void AwBrowserContext::InitUserPrefService() {
+  user_prefs::PrefRegistrySyncable* pref_registry =
+      new user_prefs::PrefRegistrySyncable();
+  // We only use the autocomplete feature of the Autofill, which is
+  // controlled via the manager_delegate. We don't use the rest
+  // of autofill, which is why it is hardcoded as disabled here.
+  pref_registry->RegisterBooleanPref(
+      autofill::prefs::kAutofillEnabled, false);
+  pref_registry->RegisterDoublePref(
+      autofill::prefs::kAutofillPositiveUploadRate, 0.0);
+  pref_registry->RegisterDoublePref(
+      autofill::prefs::kAutofillNegativeUploadRate, 0.0);
+  data_reduction_proxy::RegisterSimpleProfilePrefs(pref_registry);
+  policy::URLBlacklistManager::RegisterProfilePrefs(pref_registry);
+
+  base::PrefServiceFactory pref_service_factory;
+  pref_service_factory.set_user_prefs(make_scoped_refptr(new AwPrefStore()));
+  pref_service_factory.set_managed_prefs(
+      make_scoped_refptr(new policy::ConfigurationPolicyPrefStore(
+          browser_policy_connector_->GetPolicyService(),
+          browser_policy_connector_->GetHandlerList(),
+          policy::POLICY_LEVEL_MANDATORY)));
+  pref_service_factory.set_read_error_callback(base::Bind(&HandleReadError));
+  user_pref_service_ = pref_service_factory.Create(pref_registry).Pass();
+
+  user_prefs::UserPrefs::Set(this, user_pref_service_.get());
+}
+
+scoped_ptr<content::ZoomLevelDelegate>
+AwBrowserContext::CreateZoomLevelDelegate(
+    const base::FilePath& partition_path) {
+  return nullptr;
+}
+
+base::FilePath AwBrowserContext::GetPath() const {
+  return context_storage_path_;
+}
+
+bool AwBrowserContext::IsOffTheRecord() const {
+  // Android WebView does not support off the record profile yet.
+  return false;
+}
+
+net::URLRequestContextGetter* AwBrowserContext::GetRequestContext() {
+  return GetDefaultStoragePartition(this)->GetURLRequestContext();
+}
+
+net::URLRequestContextGetter*
+AwBrowserContext::GetRequestContextForRenderProcess(
+    int renderer_child_id) {
+  return GetRequestContext();
+}
+
+net::URLRequestContextGetter* AwBrowserContext::GetMediaRequestContext() {
+  return GetRequestContext();
+}
+
+net::URLRequestContextGetter*
+AwBrowserContext::GetMediaRequestContextForRenderProcess(
+    int renderer_child_id) {
+  return GetRequestContext();
+}
+
+net::URLRequestContextGetter*
+AwBrowserContext::GetMediaRequestContextForStoragePartition(
+    const base::FilePath& partition_path,
+    bool in_memory) {
+  NOTREACHED();
+  return NULL;
+}
+
+content::ResourceContext* AwBrowserContext::GetResourceContext() {
+  if (!resource_context_) {
+    resource_context_.reset(
+        new AwResourceContext(url_request_context_getter_.get()));
+  }
+  return resource_context_.get();
+}
+
+content::DownloadManagerDelegate*
+AwBrowserContext::GetDownloadManagerDelegate() {
+  return &download_manager_delegate_;
+}
+
+content::BrowserPluginGuestManager* AwBrowserContext::GetGuestManager() {
+  return NULL;
+}
+
+storage::SpecialStoragePolicy* AwBrowserContext::GetSpecialStoragePolicy() {
+  // Intentionally returning NULL as 'Extensions' and 'Apps' not supported.
+  return NULL;
+}
+
+content::PushMessagingService* AwBrowserContext::GetPushMessagingService() {
+  // TODO(johnme): Support push messaging in WebView.
+  return NULL;
+}
+
+content::SSLHostStateDelegate* AwBrowserContext::GetSSLHostStateDelegate() {
+  if (!ssl_host_state_delegate_.get()) {
+    ssl_host_state_delegate_.reset(new AwSSLHostStateDelegate());
+  }
+  return ssl_host_state_delegate_.get();
+}
+
+content::PermissionManager* AwBrowserContext::GetPermissionManager() {
+  if (!permission_manager_.get())
+    permission_manager_.reset(new AwPermissionManager());
+  return permission_manager_.get();
+}
+
+policy::URLBlacklistManager* AwBrowserContext::GetURLBlacklistManager() {
+  // Should not be called until the end of PreMainMessageLoopRun, where
+  // blacklist_manager_ is initialized.
+  DCHECK(blacklist_manager_);
+  return blacklist_manager_.get();
+}
+
+void AwBrowserContext::RebuildTable(
+    const scoped_refptr<URLEnumerator>& enumerator) {
+  // Android WebView rebuilds from WebChromeClient.getVisitedHistory. The client
+  // can change in the lifetime of this WebView and may not yet be set here.
+  // Therefore this initialization path is not used.
+  enumerator->OnComplete(true);
+}
+
+void AwBrowserContext::CreateDataReductionProxyStatisticsIfNecessary() {
+  DCHECK(user_pref_service_.get());
+  DCHECK(GetDataReductionProxySettings());
+  data_reduction_proxy::DataReductionProxyService*
+      data_reduction_proxy_service =
+          GetDataReductionProxySettings()->data_reduction_proxy_service();
+  DCHECK(data_reduction_proxy_service);
+  if (data_reduction_proxy_service->compression_stats())
+    return;
+  // We don't care about commit_delay for now. It is just a dummy value.
+  base::TimeDelta commit_delay = base::TimeDelta::FromMinutes(60);
+  data_reduction_proxy_service->EnableCompressionStatisticsLogging(
+      user_pref_service_.get(),
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+      commit_delay);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_browser_context.h b/android_webview/browser/aw_browser_context.h
new file mode 100644
index 0000000..053ed6a
--- /dev/null
+++ b/android_webview/browser/aw_browser_context.h
@@ -0,0 +1,177 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_BROWSER_CONTEXT_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_BROWSER_CONTEXT_H_
+
+#include <vector>
+
+#include "android_webview/browser/aw_download_manager_delegate.h"
+#include "android_webview/browser/aw_message_port_service.h"
+#include "android_webview/browser/aw_ssl_host_state_delegate.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/visitedlink/browser/visitedlink_delegate.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/content_browser_client.h"
+#include "net/url_request/url_request_job_factory.h"
+
+class GURL;
+class PrefService;
+
+namespace content {
+class PermissionManager;
+class ResourceContext;
+class SSLHostStateDelegate;
+class WebContents;
+}
+
+namespace data_reduction_proxy {
+class DataReductionProxyConfigurator;
+class DataReductionProxyIOData;
+class DataReductionProxyService;
+class DataReductionProxySettings;
+}
+
+namespace net {
+class CookieStore;
+}
+
+namespace policy {
+class URLBlacklistManager;
+class BrowserPolicyConnectorBase;
+}
+
+namespace visitedlink {
+class VisitedLinkMaster;
+}
+
+namespace android_webview {
+
+class AwFormDatabaseService;
+class AwQuotaManagerBridge;
+class AwURLRequestContextGetter;
+class JniDependencyFactory;
+
+class AwBrowserContext : public content::BrowserContext,
+                         public visitedlink::VisitedLinkDelegate {
+ public:
+
+  AwBrowserContext(const base::FilePath path,
+                   JniDependencyFactory* native_factory);
+  ~AwBrowserContext() override;
+
+  // Currently only one instance per process is supported.
+  static AwBrowserContext* GetDefault();
+
+  // Convenience method to returns the AwBrowserContext corresponding to the
+  // given WebContents.
+  static AwBrowserContext* FromWebContents(
+      content::WebContents* web_contents);
+
+  static void SetDataReductionProxyEnabled(bool enabled);
+  static void SetLegacyCacheRemovalDelayForTest(int delay_ms);
+
+  // Maps to BrowserMainParts::PreMainMessageLoopRun.
+  void PreMainMessageLoopRun();
+
+  // These methods map to Add methods in visitedlink::VisitedLinkMaster.
+  void AddVisitedURLs(const std::vector<GURL>& urls);
+
+  net::URLRequestContextGetter* CreateRequestContext(
+      content::ProtocolHandlerMap* protocol_handlers,
+      content::URLRequestInterceptorScopedVector request_interceptors);
+  net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      const base::FilePath& partition_path,
+      bool in_memory,
+      content::ProtocolHandlerMap* protocol_handlers,
+      content::URLRequestInterceptorScopedVector request_interceptors);
+
+  AwQuotaManagerBridge* GetQuotaManagerBridge();
+
+  AwFormDatabaseService* GetFormDatabaseService();
+
+  data_reduction_proxy::DataReductionProxySettings*
+      GetDataReductionProxySettings();
+
+  data_reduction_proxy::DataReductionProxyIOData*
+      GetDataReductionProxyIOData();
+
+  AwURLRequestContextGetter* GetAwURLRequestContext();
+
+  AwMessagePortService* GetMessagePortService();
+
+  policy::URLBlacklistManager* GetURLBlacklistManager();
+
+  // content::BrowserContext implementation.
+  scoped_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(
+      const base::FilePath& partition_path) override;
+  base::FilePath GetPath() const override;
+  bool IsOffTheRecord() const override;
+  net::URLRequestContextGetter* GetRequestContext() override;
+  net::URLRequestContextGetter* GetRequestContextForRenderProcess(
+      int renderer_child_id) override;
+  net::URLRequestContextGetter* GetMediaRequestContext() override;
+  net::URLRequestContextGetter* GetMediaRequestContextForRenderProcess(
+      int renderer_child_id) override;
+  net::URLRequestContextGetter* GetMediaRequestContextForStoragePartition(
+      const base::FilePath& partition_path,
+      bool in_memory) override;
+  content::ResourceContext* GetResourceContext() override;
+  content::DownloadManagerDelegate* GetDownloadManagerDelegate() override;
+  content::BrowserPluginGuestManager* GetGuestManager() override;
+  storage::SpecialStoragePolicy* GetSpecialStoragePolicy() override;
+  content::PushMessagingService* GetPushMessagingService() override;
+  content::SSLHostStateDelegate* GetSSLHostStateDelegate() override;
+  content::PermissionManager* GetPermissionManager() override;
+
+  // visitedlink::VisitedLinkDelegate implementation.
+  void RebuildTable(const scoped_refptr<URLEnumerator>& enumerator) override;
+
+ private:
+  void InitUserPrefService();
+  void CreateDataReductionProxyStatisticsIfNecessary();
+  static bool data_reduction_proxy_enabled_;
+
+  // Delay, in milliseconds, before removing the legacy cache dir.
+  // This is non-const for testing purposes.
+  static int legacy_cache_removal_delay_ms_;
+
+  // The file path where data for this context is persisted.
+  base::FilePath context_storage_path_;
+
+  JniDependencyFactory* native_factory_;
+  scoped_refptr<net::CookieStore> cookie_store_;
+  scoped_refptr<AwURLRequestContextGetter> url_request_context_getter_;
+  scoped_refptr<AwQuotaManagerBridge> quota_manager_bridge_;
+  scoped_ptr<AwFormDatabaseService> form_database_service_;
+  scoped_ptr<AwMessagePortService> message_port_service_;
+
+  AwDownloadManagerDelegate download_manager_delegate_;
+
+  scoped_ptr<visitedlink::VisitedLinkMaster> visitedlink_master_;
+  scoped_ptr<content::ResourceContext> resource_context_;
+
+  scoped_ptr<PrefService> user_pref_service_;
+  scoped_ptr<policy::BrowserPolicyConnectorBase> browser_policy_connector_;
+  scoped_ptr<policy::URLBlacklistManager> blacklist_manager_;
+
+  scoped_ptr<data_reduction_proxy::DataReductionProxySettings>
+      data_reduction_proxy_settings_;
+  scoped_ptr<AwSSLHostStateDelegate> ssl_host_state_delegate_;
+  scoped_ptr<data_reduction_proxy::DataReductionProxyIOData>
+      data_reduction_proxy_io_data_;
+  scoped_ptr<data_reduction_proxy::DataReductionProxyService>
+      data_reduction_proxy_service_;
+  scoped_ptr<content::PermissionManager> permission_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwBrowserContext);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_BROWSER_CONTEXT_H_
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc
new file mode 100644
index 0000000..6fc5154
--- /dev/null
+++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -0,0 +1,115 @@
+// 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 "android_webview/browser/aw_browser_main_parts.h"
+
+#include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/browser/aw_dev_tools_discovery_provider.h"
+#include "android_webview/browser/aw_media_client_android.h"
+#include "android_webview/browser/aw_result_codes.h"
+#include "android_webview/browser/deferred_gpu_command_service.h"
+#include "android_webview/common/aw_resource.h"
+#include "android_webview/common/aw_switches.h"
+#include "base/android/apk_assets.h"
+#include "base/android/build_info.h"
+#include "base/android/locale_utils.h"
+#include "base/android/memory_pressure_listener_android.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/path_service.h"
+#include "content/public/browser/android/synchronous_compositor.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/result_codes.h"
+#include "content/public/common/url_utils.h"
+#include "media/base/android/media_client_android.h"
+#include "net/android/network_change_notifier_factory_android.h"
+#include "net/base/network_change_notifier.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/layout.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/resource/resource_bundle_android.h"
+#include "ui/base/ui_base_paths.h"
+#include "ui/gl/gl_surface.h"
+
+namespace android_webview {
+
+AwBrowserMainParts::AwBrowserMainParts(AwBrowserContext* browser_context)
+    : browser_context_(browser_context) {
+}
+
+AwBrowserMainParts::~AwBrowserMainParts() {
+}
+
+void AwBrowserMainParts::PreEarlyInitialization() {
+  net::NetworkChangeNotifier::SetFactory(
+      new net::NetworkChangeNotifierFactoryAndroid());
+
+  // Android WebView does not use default MessageLoop. It has its own
+  // Android specific MessageLoop. Also see MainMessageLoopRun.
+  DCHECK(!main_message_loop_.get());
+  main_message_loop_.reset(new base::MessageLoopForUI);
+  base::MessageLoopForUI::current()->Start();
+}
+
+int AwBrowserMainParts::PreCreateThreads() {
+  ui::SetLocalePaksStoredInApk(true);
+  std::string locale = ui::ResourceBundle::InitSharedInstanceWithLocale(
+      base::android::GetDefaultLocale(),
+      NULL,
+      ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);
+  if (locale.empty()) {
+    LOG(WARNING) << "Failed to load locale .pak from the apk. "
+        "Bringing up WebView without any locale";
+  }
+
+  // Try to directly mmap the webviewchromium.pak from the apk. Fall back to
+  // load from file, using PATH_SERVICE, otherwise.
+  base::FilePath pak_file_path;
+  PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &pak_file_path);
+  pak_file_path = pak_file_path.AppendASCII("webviewchromium.pak");
+  ui::LoadMainAndroidPackFile("assets/webviewchromium.pak", pak_file_path);
+
+  base::android::MemoryPressureListenerAndroid::RegisterSystemCallback(
+      base::android::AttachCurrentThread());
+  DeferredGpuCommandService::SetInstance();
+
+  return content::RESULT_CODE_NORMAL_EXIT;
+}
+
+void AwBrowserMainParts::PreMainMessageLoopRun() {
+  browser_context_->PreMainMessageLoopRun();
+
+  AwDevToolsDiscoveryProvider::Install();
+
+  media::SetMediaClientAndroid(
+      new AwMediaClientAndroid(AwResource::GetConfigKeySystemUuidMapping()));
+
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kUseIpcCommandBuffer)) {
+    content::SynchronousCompositor::SetUseIpcCommandBuffer();
+  } else {
+    gfx::GLSurface::InitializeOneOff();
+  }
+
+  content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
+
+  // This is needed for WebView Classic backwards compatibility
+  // See crbug.com/298495. Also see crbug.com/525697 on why it is currently
+  // for single process mode only.
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kSingleProcess)) {
+    content::SetMaxURLChars(20 * 1024 * 1024);
+  }
+}
+
+bool AwBrowserMainParts::MainMessageLoopRun(int* result_code) {
+  // Android WebView does not use default MessageLoop. It has its own
+  // Android specific MessageLoop.
+  return true;
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_browser_main_parts.h b/android_webview/browser/aw_browser_main_parts.h
new file mode 100644
index 0000000..2f417c0
--- /dev/null
+++ b/android_webview/browser/aw_browser_main_parts.h
@@ -0,0 +1,42 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_BROWSER_MAIN_PARTS_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_BROWSER_MAIN_PARTS_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/browser_main_parts.h"
+
+namespace base {
+class MessageLoop;
+}
+
+namespace android_webview {
+
+class AwBrowserContext;
+
+class AwBrowserMainParts : public content::BrowserMainParts {
+ public:
+  explicit AwBrowserMainParts(AwBrowserContext* browser_context);
+  ~AwBrowserMainParts() override;
+
+  // Overriding methods from content::BrowserMainParts.
+  void PreEarlyInitialization() override;
+  int PreCreateThreads() override;
+  void PreMainMessageLoopRun() override;
+  bool MainMessageLoopRun(int* result_code) override;
+
+ private:
+  // Android specific UI MessageLoop.
+  scoped_ptr<base::MessageLoop> main_message_loop_;
+
+  AwBrowserContext* browser_context_;  // weak
+
+  DISALLOW_COPY_AND_ASSIGN(AwBrowserMainParts);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_BROWSER_MAIN_PARTS_H_
diff --git a/android_webview/browser/aw_browser_permission_request_delegate.h b/android_webview/browser/aw_browser_permission_request_delegate.h
new file mode 100644
index 0000000..a0144a1
--- /dev/null
+++ b/android_webview/browser/aw_browser_permission_request_delegate.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 ANDROID_WEBVIEW_BROWSER_AW_BROWSER_PERMISSION_REQUEST_DELEGATE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_BROWSER_PERMISSION_REQUEST_DELEGATE_H_
+
+#include "base/callback_forward.h"
+#include "url/gurl.h"
+
+namespace android_webview {
+
+// Delegate interface to handle the permission requests from |BrowserContext|.
+class AwBrowserPermissionRequestDelegate {
+ public:
+  // Returns the AwBrowserPermissionRequestDelegate instance associated with
+  // the given render_process_id and render_frame_id, or NULL.
+  static AwBrowserPermissionRequestDelegate* FromID(int render_process_id,
+                                                    int render_frame_id);
+
+  virtual void RequestProtectedMediaIdentifierPermission(
+      const GURL& origin,
+      const base::Callback<void(bool)>& callback) = 0;
+
+  virtual void CancelProtectedMediaIdentifierPermissionRequests(
+      const GURL& origin) = 0;
+
+  virtual void RequestGeolocationPermission(
+      const GURL& origin,
+      const base::Callback<void(bool)>& callback) = 0;
+
+  virtual void CancelGeolocationPermissionRequests(const GURL& origin) = 0;
+
+  virtual void RequestMIDISysexPermission(
+      const GURL& origin,
+      const base::Callback<void(bool)>& callback) = 0;
+
+  virtual void CancelMIDISysexPermissionRequests(const GURL& origin) = 0;
+
+ protected:
+  AwBrowserPermissionRequestDelegate() {}
+};
+
+}  // namespace android_webview
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_BROWSER_PERMISSION_REQUEST_DELEGATE_H_
diff --git a/android_webview/browser/aw_browser_policy_connector.cc b/android_webview/browser/aw_browser_policy_connector.cc
new file mode 100644
index 0000000..f0e03ea
--- /dev/null
+++ b/android_webview/browser/aw_browser_policy_connector.cc
@@ -0,0 +1,57 @@
+// Copyright 2015 The Chromium Authors. 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/aw_browser_policy_connector.h"
+
+#include "base/bind.h"
+#include "components/policy/core/browser/android/android_combined_policy_provider.h"
+#include "components/policy/core/browser/configuration_policy_handler_list.h"
+#include "components/policy/core/browser/url_blacklist_policy_handler.h"
+#include "components/policy/core/common/policy_pref_names.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "policy/policy_constants.h"
+
+namespace android_webview {
+
+namespace {
+
+// Callback only used in ChromeOS. No-op here.
+void PopulatePolicyHandlerParameters(
+    policy::PolicyHandlerParameters* parameters) {}
+
+// Used to check if a policy is deprecated. Currently bypasses that check.
+const policy::PolicyDetails* GetChromePolicyDetails(const std::string& policy) {
+  return nullptr;
+}
+
+// Factory for the handlers that will be responsible for converting the policies
+// to the associated preferences.
+scoped_ptr<policy::ConfigurationPolicyHandlerList> BuildHandlerList(
+    const policy::Schema& chrome_schema) {
+  scoped_ptr<policy::ConfigurationPolicyHandlerList> handlers(
+      new policy::ConfigurationPolicyHandlerList(
+          base::Bind(&PopulatePolicyHandlerParameters),
+          base::Bind(&GetChromePolicyDetails)));
+
+  handlers->AddHandler(make_scoped_ptr(new policy::SimplePolicyHandler(
+      policy::key::kURLWhitelist, policy::policy_prefs::kUrlWhitelist,
+      base::Value::TYPE_LIST)));
+
+  handlers->AddHandler(
+      make_scoped_ptr(new policy::URLBlacklistPolicyHandler()));
+  return handlers.Pass();
+}
+
+}  // namespace
+
+AwBrowserPolicyConnector::AwBrowserPolicyConnector()
+   : BrowserPolicyConnectorBase(base::Bind(&BuildHandlerList)) {
+ SetPlatformPolicyProvider(make_scoped_ptr(
+     new policy::android::AndroidCombinedPolicyProvider(GetSchemaRegistry())));
+ InitPolicyProviders();
+}
+
+AwBrowserPolicyConnector::~AwBrowserPolicyConnector() {}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_browser_policy_connector.h b/android_webview/browser/aw_browser_policy_connector.h
new file mode 100644
index 0000000..49d5001
--- /dev/null
+++ b/android_webview/browser/aw_browser_policy_connector.h
@@ -0,0 +1,25 @@
+// Copyright 2015 The Chromium Authors. 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_AW_BROWSER_POLICY_CONNECTOR_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_BROWSER_POLICY_CONNECTOR_H_
+
+#include "components/policy/core/browser/browser_policy_connector_base.h"
+
+namespace android_webview {
+
+// Sets up and keeps the browser-global policy objects such as the PolicyService
+// and the platform-specific PolicyProvider.
+class AwBrowserPolicyConnector : public policy::BrowserPolicyConnectorBase {
+public:
+ AwBrowserPolicyConnector();
+ ~AwBrowserPolicyConnector() override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AwBrowserPolicyConnector);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_BROWSER_POLICY_CONNECTOR_H_
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
new file mode 100644
index 0000000..759c844
--- /dev/null
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -0,0 +1,498 @@
+// 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 "android_webview/browser/aw_content_browser_client.h"
+
+#include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/browser/aw_browser_main_parts.h"
+#include "android_webview/browser/aw_contents_client_bridge_base.h"
+#include "android_webview/browser/aw_contents_io_thread_client.h"
+#include "android_webview/browser/aw_cookie_access_policy.h"
+#include "android_webview/browser/aw_locale_manager.h"
+#include "android_webview/browser/aw_printing_message_filter.h"
+#include "android_webview/browser/aw_quota_permission_context.h"
+#include "android_webview/browser/aw_web_preferences_populater.h"
+#include "android_webview/browser/jni_dependency_factory.h"
+#include "android_webview/browser/net/aw_url_request_context_getter.h"
+#include "android_webview/browser/net_disk_cache_remover.h"
+#include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h"
+#include "android_webview/common/aw_descriptors.h"
+#include "android_webview/common/render_view_messages.h"
+#include "android_webview/common/url_constants.h"
+#include "base/android/locale_utils.h"
+#include "base/base_paths_android.h"
+#include "base/command_line.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/child_process_security_policy.h"
+#include "content/public/browser/client_certificate_delegate.h"
+#include "content/public/browser/render_frame_host.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 "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/common/web_preferences.h"
+#include "net/android/network_library.h"
+#include "net/ssl/ssl_cert_request_info.h"
+#include "net/ssl/ssl_info.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/resource/resource_bundle_android.h"
+#include "ui/resources/grit/ui_resources.h"
+
+using content::ResourceType;
+
+namespace android_webview {
+namespace {
+
+// TODO(sgurun) move this to its own file.
+// This class filters out incoming aw_contents related IPC messages for the
+// renderer process on the IPC thread.
+class AwContentsMessageFilter : public content::BrowserMessageFilter {
+public:
+  explicit AwContentsMessageFilter(int process_id);
+
+  // BrowserMessageFilter methods.
+  bool OnMessageReceived(const IPC::Message& message) override;
+
+  void OnSubFrameCreated(int parent_render_frame_id, int child_render_frame_id);
+
+private:
+ ~AwContentsMessageFilter() override;
+
+  int process_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwContentsMessageFilter);
+};
+
+AwContentsMessageFilter::AwContentsMessageFilter(int process_id)
+    : BrowserMessageFilter(AndroidWebViewMsgStart),
+      process_id_(process_id) {
+}
+
+AwContentsMessageFilter::~AwContentsMessageFilter() {
+}
+
+bool AwContentsMessageFilter::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(AwContentsMessageFilter, message)
+    IPC_MESSAGE_HANDLER(AwViewHostMsg_SubFrameCreated, OnSubFrameCreated)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void AwContentsMessageFilter::OnSubFrameCreated(int parent_render_frame_id,
+                                                int child_render_frame_id) {
+  AwContentsIoThreadClient::SubFrameCreated(
+      process_id_, parent_render_frame_id, child_render_frame_id);
+}
+
+class AwAccessTokenStore : public content::AccessTokenStore {
+ public:
+  AwAccessTokenStore() { }
+
+  // content::AccessTokenStore implementation
+  void LoadAccessTokens(const LoadAccessTokensCallbackType& request) override {
+    AccessTokenStore::AccessTokenSet access_token_set;
+    // AccessTokenSet and net::URLRequestContextGetter not used on Android,
+    // but Run needs to be called to finish the geolocation setup.
+    request.Run(access_token_set, NULL);
+  }
+  void SaveAccessToken(const GURL& server_url,
+                       const base::string16& access_token) override {}
+
+ private:
+  ~AwAccessTokenStore() override {}
+
+  DISALLOW_COPY_AND_ASSIGN(AwAccessTokenStore);
+};
+
+AwLocaleManager* g_locale_manager = NULL;
+
+}  // anonymous namespace
+
+// static
+std::string AwContentBrowserClient::GetAcceptLangsImpl() {
+  // Start with the current locale.
+  std::string langs = g_locale_manager->GetLocale();
+
+  // If we're not en-US, add in en-US which will be
+  // used with a lower q-value.
+  if (base::ToLowerASCII(langs) != "en-us") {
+    langs += ",en-US";
+  }
+  return langs;
+}
+
+// static
+AwBrowserContext* AwContentBrowserClient::GetAwBrowserContext() {
+  return AwBrowserContext::GetDefault();
+}
+
+AwContentBrowserClient::AwContentBrowserClient(
+    JniDependencyFactory* native_factory)
+    : native_factory_(native_factory) {
+  base::FilePath user_data_dir;
+  if (!PathService::Get(base::DIR_ANDROID_APP_DATA, &user_data_dir)) {
+    NOTREACHED() << "Failed to get app data directory for Android WebView";
+  }
+  browser_context_.reset(
+      new AwBrowserContext(user_data_dir, native_factory_));
+  g_locale_manager = native_factory->CreateAwLocaleManager();
+}
+
+AwContentBrowserClient::~AwContentBrowserClient() {
+  delete g_locale_manager;
+  g_locale_manager = NULL;
+}
+
+void AwContentBrowserClient::AddCertificate(net::CertificateMimeType cert_type,
+                                            const void* cert_data,
+                                            size_t cert_size,
+                                            int render_process_id,
+                                            int render_frame_id) {
+  if (cert_size > 0)
+    net::android::StoreCertificate(cert_type, cert_data, cert_size);
+}
+
+content::BrowserMainParts* AwContentBrowserClient::CreateBrowserMainParts(
+    const content::MainFunctionParams& parameters) {
+  return new AwBrowserMainParts(browser_context_.get());
+}
+
+content::WebContentsViewDelegate*
+AwContentBrowserClient::GetWebContentsViewDelegate(
+    content::WebContents* web_contents) {
+  return native_factory_->CreateViewDelegate(web_contents);
+}
+
+void AwContentBrowserClient::RenderProcessWillLaunch(
+    content::RenderProcessHost* host) {
+  // Grant content: scheme access to the whole renderer process, since we impose
+  // per-view access checks, and access is granted by default (see
+  // AwSettings.mAllowContentUrlAccess).
+  content::ChildProcessSecurityPolicy::GetInstance()->GrantScheme(
+      host->GetID(), url::kContentScheme);
+
+  host->AddFilter(new AwContentsMessageFilter(host->GetID()));
+  host->AddFilter(new cdm::CdmMessageFilterAndroid());
+  host->AddFilter(new AwPrintingMessageFilter(host->GetID()));
+}
+
+net::URLRequestContextGetter* AwContentBrowserClient::CreateRequestContext(
+    content::BrowserContext* browser_context,
+    content::ProtocolHandlerMap* protocol_handlers,
+    content::URLRequestInterceptorScopedVector request_interceptors) {
+  DCHECK_EQ(browser_context_.get(), browser_context);
+  return browser_context_->CreateRequestContext(protocol_handlers,
+                                                request_interceptors.Pass());
+}
+
+net::URLRequestContextGetter*
+AwContentBrowserClient::CreateRequestContextForStoragePartition(
+    content::BrowserContext* browser_context,
+    const base::FilePath& partition_path,
+    bool in_memory,
+    content::ProtocolHandlerMap* protocol_handlers,
+    content::URLRequestInterceptorScopedVector request_interceptors) {
+  DCHECK_EQ(browser_context_.get(), browser_context);
+  // TODO(mkosiba,kinuko): request_interceptors should be hooked up in the
+  // downstream. (crbug.com/350286)
+  return browser_context_->CreateRequestContextForStoragePartition(
+      partition_path, in_memory, protocol_handlers,
+      request_interceptors.Pass());
+}
+
+bool AwContentBrowserClient::IsHandledURL(const GURL& url) {
+  if (!url.is_valid()) {
+    // We handle error cases.
+    return true;
+  }
+
+  const std::string scheme = url.scheme();
+  DCHECK_EQ(scheme, base::ToLowerASCII(scheme));
+  // See CreateJobFactory in aw_url_request_context_getter.cc for the
+  // list of protocols that are handled.
+  // TODO(mnaganov): Make this automatic.
+  static const char* const kProtocolList[] = {
+    url::kDataScheme,
+    url::kBlobScheme,
+    url::kFileSystemScheme,
+    content::kChromeUIScheme,
+    content::kChromeDevToolsScheme,
+    url::kContentScheme,
+  };
+  if (scheme == url::kFileScheme) {
+    // Return false for the "special" file URLs, so they can be loaded
+    // even if access to file: scheme is not granted to the child process.
+    return !IsAndroidSpecialFileUrl(url);
+  }
+  for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
+    if (scheme == kProtocolList[i])
+      return true;
+  }
+  return net::URLRequest::IsHandledProtocol(scheme);
+}
+
+std::string AwContentBrowserClient::GetCanonicalEncodingNameByAliasName(
+    const std::string& alias_name) {
+  return alias_name;
+}
+
+void AwContentBrowserClient::AppendExtraCommandLineSwitches(
+    base::CommandLine* command_line,
+    int child_process_id) {
+  if (command_line->HasSwitch(switches::kSingleProcess)) {
+    NOTREACHED() << "Android WebView does not support multi-process yet";
+  } else {
+    // The only kind of a child process WebView can have is renderer.
+    DCHECK_EQ(switches::kRendererProcess,
+              command_line->GetSwitchValueASCII(switches::kProcessType));
+  }
+}
+
+std::string AwContentBrowserClient::GetApplicationLocale() {
+  return base::android::GetDefaultLocale();
+}
+
+std::string AwContentBrowserClient::GetAcceptLangs(
+    content::BrowserContext* context) {
+  return GetAcceptLangsImpl();
+}
+
+const gfx::ImageSkia* AwContentBrowserClient::GetDefaultFavicon() {
+  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+  // TODO(boliu): Bundle our own default favicon?
+  return rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
+}
+
+bool AwContentBrowserClient::AllowAppCache(const GURL& manifest_url,
+                           const GURL& first_party,
+                           content::ResourceContext* context) {
+  // WebView doesn't have a per-site policy for locally stored data,
+  // instead AppCache can be disabled for individual WebViews.
+  return true;
+}
+
+
+bool AwContentBrowserClient::AllowGetCookie(const GURL& url,
+                                            const GURL& first_party,
+                                            const net::CookieList& cookie_list,
+                                            content::ResourceContext* context,
+                                            int render_process_id,
+                                            int render_frame_id) {
+  return AwCookieAccessPolicy::GetInstance()->AllowGetCookie(url,
+                                                             first_party,
+                                                             cookie_list,
+                                                             context,
+                                                             render_process_id,
+                                                             render_frame_id);
+}
+
+bool AwContentBrowserClient::AllowSetCookie(const GURL& url,
+                                            const GURL& first_party,
+                                            const std::string& cookie_line,
+                                            content::ResourceContext* context,
+                                            int render_process_id,
+                                            int render_frame_id,
+                                            net::CookieOptions* options) {
+  return AwCookieAccessPolicy::GetInstance()->AllowSetCookie(url,
+                                                             first_party,
+                                                             cookie_line,
+                                                             context,
+                                                             render_process_id,
+                                                             render_frame_id,
+                                                             options);
+}
+
+bool AwContentBrowserClient::AllowWorkerDatabase(
+    const GURL& url,
+    const base::string16& name,
+    const base::string16& display_name,
+    unsigned long estimated_size,
+    content::ResourceContext* context,
+    const std::vector<std::pair<int, int> >& render_frames) {
+  // Android WebView does not yet support web workers.
+  return false;
+}
+
+void AwContentBrowserClient::AllowWorkerFileSystem(
+    const GURL& url,
+    content::ResourceContext* context,
+    const std::vector<std::pair<int, int> >& render_frames,
+    base::Callback<void(bool)> callback) {
+  // Android WebView does not yet support web workers.
+  callback.Run(false);
+}
+
+bool AwContentBrowserClient::AllowWorkerIndexedDB(
+    const GURL& url,
+    const base::string16& name,
+    content::ResourceContext* context,
+    const std::vector<std::pair<int, int> >& render_frames) {
+  // Android WebView does not yet support web workers.
+  return false;
+}
+
+content::QuotaPermissionContext*
+AwContentBrowserClient::CreateQuotaPermissionContext() {
+  return new AwQuotaPermissionContext;
+}
+
+void AwContentBrowserClient::AllowCertificateError(
+    int render_process_id,
+    int render_frame_id,
+    int cert_error,
+    const net::SSLInfo& ssl_info,
+    const GURL& request_url,
+    ResourceType resource_type,
+    bool overridable,
+    bool strict_enforcement,
+    bool expired_previous_decision,
+    const base::Callback<void(bool)>& callback,
+    content::CertificateRequestResultType* result) {
+  AwContentsClientBridgeBase* client =
+      AwContentsClientBridgeBase::FromID(render_process_id, render_frame_id);
+  bool cancel_request = true;
+  if (client)
+    client->AllowCertificateError(cert_error,
+                                  ssl_info.cert.get(),
+                                  request_url,
+                                  callback,
+                                  &cancel_request);
+  if (cancel_request)
+    *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
+}
+
+void AwContentBrowserClient::SelectClientCertificate(
+    content::WebContents* web_contents,
+    net::SSLCertRequestInfo* cert_request_info,
+    scoped_ptr<content::ClientCertificateDelegate> delegate) {
+  AwContentsClientBridgeBase* client =
+      AwContentsClientBridgeBase::FromWebContents(web_contents);
+  if (client)
+    client->SelectClientCertificate(cert_request_info, delegate.Pass());
+}
+
+bool AwContentBrowserClient::CanCreateWindow(
+    const GURL& opener_url,
+    const GURL& opener_top_level_frame_url,
+    const GURL& source_origin,
+    WindowContainerType container_type,
+    const GURL& target_url,
+    const content::Referrer& referrer,
+    WindowOpenDisposition disposition,
+    const blink::WebWindowFeatures& features,
+    bool user_gesture,
+    bool opener_suppressed,
+    content::ResourceContext* context,
+    int render_process_id,
+    int opener_render_view_id,
+    int opener_render_frame_id,
+    bool* no_javascript_access) {
+  // We unconditionally allow popup windows at this stage and will give
+  // the embedder the opporunity to handle displaying of the popup in
+  // WebContentsDelegate::AddContents (via the
+  // AwContentsClient.onCreateWindow callback).
+  // Note that if the embedder has blocked support for creating popup
+  // windows through AwSettings, then we won't get to this point as
+  // the popup creation will have been blocked at the WebKit level.
+  if (no_javascript_access) {
+    *no_javascript_access = false;
+  }
+  return true;
+}
+
+void AwContentBrowserClient::ResourceDispatcherHostCreated() {
+  AwResourceDispatcherHostDelegate::ResourceDispatcherHostCreated();
+}
+
+net::NetLog* AwContentBrowserClient::GetNetLog() {
+  return browser_context_->GetAwURLRequestContext()->GetNetLog();
+}
+
+content::AccessTokenStore* AwContentBrowserClient::CreateAccessTokenStore() {
+  return new AwAccessTokenStore();
+}
+
+bool AwContentBrowserClient::IsFastShutdownPossible() {
+  NOTREACHED() << "Android WebView is single process, so IsFastShutdownPossible"
+               << " should never be called";
+  return false;
+}
+
+void AwContentBrowserClient::ClearCache(content::RenderFrameHost* rfh) {
+  RemoveHttpDiskCache(rfh->GetProcess()->GetBrowserContext(),
+                      rfh->GetProcess()->GetID());
+}
+
+void AwContentBrowserClient::ClearCookies(content::RenderFrameHost* rfh) {
+  // TODO(boliu): Implement.
+  NOTIMPLEMENTED();
+}
+
+base::FilePath AwContentBrowserClient::GetDefaultDownloadDirectory() {
+  // Android WebView does not currently use the Chromium downloads system.
+  // Download requests are cancelled immedately when recognized; see
+  // AwResourceDispatcherHost::CreateResourceHandlerForDownload. However the
+  // download system still tries to start up and calls this before recognizing
+  // the request has been cancelled.
+  return base::FilePath();
+}
+
+std::string AwContentBrowserClient::GetDefaultDownloadName() {
+  NOTREACHED() << "Android WebView does not use chromium downloads";
+  return std::string();
+}
+
+void AwContentBrowserClient::DidCreatePpapiPlugin(
+    content::BrowserPpapiHost* browser_host) {
+  NOTREACHED() << "Android WebView does not support plugins";
+}
+
+bool AwContentBrowserClient::AllowPepperSocketAPI(
+    content::BrowserContext* browser_context,
+    const GURL& url,
+    bool private_api,
+    const content::SocketPermissionRequest* params) {
+  NOTREACHED() << "Android WebView does not support plugins";
+  return false;
+}
+
+void AwContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
+      const base::CommandLine& command_line,
+      int child_process_id,
+      content::FileDescriptorInfo* mappings,
+      std::map<int, base::MemoryMappedFile::Region>* regions) {
+  int fd = ui::GetMainAndroidPackFd(
+      &(*regions)[kAndroidWebViewMainPakDescriptor]);
+  mappings->Share(kAndroidWebViewMainPakDescriptor, fd);
+
+  fd = ui::GetLocalePackFd(&(*regions)[kAndroidWebViewLocalePakDescriptor]);
+  mappings->Share(kAndroidWebViewLocalePakDescriptor, fd);
+}
+
+void AwContentBrowserClient::OverrideWebkitPrefs(
+    content::RenderViewHost* rvh,
+    content::WebPreferences* web_prefs) {
+  if (!preferences_populater_.get()) {
+    preferences_populater_ = make_scoped_ptr(native_factory_->
+        CreateWebPreferencesPopulater());
+  }
+  preferences_populater_->PopulateFor(
+      content::WebContents::FromRenderViewHost(rvh), web_prefs);
+}
+
+#if defined(VIDEO_HOLE)
+content::ExternalVideoSurfaceContainer*
+AwContentBrowserClient::OverrideCreateExternalVideoSurfaceContainer(
+    content::WebContents* web_contents) {
+  return native_factory_->CreateExternalVideoSurfaceContainer(web_contents);
+}
+#endif
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
new file mode 100644
index 0000000..d811cf2
--- /dev/null
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -0,0 +1,164 @@
+// 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 ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_
+#define ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_
+
+#include "android_webview/browser/aw_web_preferences_populater.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/content_browser_client.h"
+
+namespace android_webview {
+
+class AwBrowserContext;
+class JniDependencyFactory;
+
+class AwContentBrowserClient : public content::ContentBrowserClient {
+ public:
+  // This is what AwContentBrowserClient::GetAcceptLangs uses.
+  static std::string GetAcceptLangsImpl();
+
+  // Deprecated: use AwBrowserContext::GetDefault() instead.
+  static AwBrowserContext* GetAwBrowserContext();
+
+  AwContentBrowserClient(JniDependencyFactory* native_factory);
+  ~AwContentBrowserClient() override;
+
+  // Overriden methods from ContentBrowserClient.
+  void AddCertificate(net::CertificateMimeType cert_type,
+                      const void* cert_data,
+                      size_t cert_size,
+                      int render_process_id,
+                      int render_frame_id) override;
+  content::BrowserMainParts* CreateBrowserMainParts(
+      const content::MainFunctionParams& parameters) override;
+  content::WebContentsViewDelegate* GetWebContentsViewDelegate(
+      content::WebContents* web_contents) override;
+  void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
+  net::URLRequestContextGetter* CreateRequestContext(
+      content::BrowserContext* browser_context,
+      content::ProtocolHandlerMap* protocol_handlers,
+      content::URLRequestInterceptorScopedVector request_interceptors) override;
+  net::URLRequestContextGetter* CreateRequestContextForStoragePartition(
+      content::BrowserContext* browser_context,
+      const base::FilePath& partition_path,
+      bool in_memory,
+      content::ProtocolHandlerMap* protocol_handlers,
+      content::URLRequestInterceptorScopedVector request_interceptors) override;
+  bool IsHandledURL(const GURL& url) override;
+  std::string GetCanonicalEncodingNameByAliasName(
+      const std::string& alias_name) override;
+  void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
+                                      int child_process_id) override;
+  std::string GetApplicationLocale() override;
+  std::string GetAcceptLangs(content::BrowserContext* context) override;
+  const gfx::ImageSkia* GetDefaultFavicon() override;
+  bool AllowAppCache(const GURL& manifest_url,
+                     const GURL& first_party,
+                     content::ResourceContext* context) override;
+  bool AllowGetCookie(const GURL& url,
+                      const GURL& first_party,
+                      const net::CookieList& cookie_list,
+                      content::ResourceContext* context,
+                      int render_process_id,
+                      int render_frame_id) override;
+  bool AllowSetCookie(const GURL& url,
+                      const GURL& first_party,
+                      const std::string& cookie_line,
+                      content::ResourceContext* context,
+                      int render_process_id,
+                      int render_frame_id,
+                      net::CookieOptions* options) override;
+  bool AllowWorkerDatabase(
+      const GURL& url,
+      const base::string16& name,
+      const base::string16& display_name,
+      unsigned long estimated_size,
+      content::ResourceContext* context,
+      const std::vector<std::pair<int, int>>& render_frames) override;
+  void AllowWorkerFileSystem(
+      const GURL& url,
+      content::ResourceContext* context,
+      const std::vector<std::pair<int, int>>& render_frames,
+      base::Callback<void(bool)> callback) override;
+  bool AllowWorkerIndexedDB(
+      const GURL& url,
+      const base::string16& name,
+      content::ResourceContext* context,
+      const std::vector<std::pair<int, int>>& render_frames) override;
+  content::QuotaPermissionContext* CreateQuotaPermissionContext() override;
+  void AllowCertificateError(
+      int render_process_id,
+      int render_frame_id,
+      int cert_error,
+      const net::SSLInfo& ssl_info,
+      const GURL& request_url,
+      content::ResourceType resource_type,
+      bool overridable,
+      bool strict_enforcement,
+      bool expired_previous_decision,
+      const base::Callback<void(bool)>& callback,
+      content::CertificateRequestResultType* result) override;
+  void SelectClientCertificate(
+      content::WebContents* web_contents,
+      net::SSLCertRequestInfo* cert_request_info,
+      scoped_ptr<content::ClientCertificateDelegate> delegate) override;
+  bool CanCreateWindow(const GURL& opener_url,
+                       const GURL& opener_top_level_frame_url,
+                       const GURL& source_origin,
+                       WindowContainerType container_type,
+                       const GURL& target_url,
+                       const content::Referrer& referrer,
+                       WindowOpenDisposition disposition,
+                       const blink::WebWindowFeatures& features,
+                       bool user_gesture,
+                       bool opener_suppressed,
+                       content::ResourceContext* context,
+                       int render_process_id,
+                       int opener_render_view_id,
+                       int opener_render_frame_id,
+                       bool* no_javascript_access) override;
+  void ResourceDispatcherHostCreated() override;
+  net::NetLog* GetNetLog() override;
+  content::AccessTokenStore* CreateAccessTokenStore() override;
+  bool IsFastShutdownPossible() override;
+  void ClearCache(content::RenderFrameHost* rfh) override;
+  void ClearCookies(content::RenderFrameHost* rfh) override;
+  base::FilePath GetDefaultDownloadDirectory() override;
+  std::string GetDefaultDownloadName() override;
+  void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
+  bool AllowPepperSocketAPI(
+      content::BrowserContext* browser_context,
+      const GURL& url,
+      bool private_api,
+      const content::SocketPermissionRequest* params) override;
+  void GetAdditionalMappedFilesForChildProcess(
+      const base::CommandLine& command_line,
+      int child_process_id,
+      content::FileDescriptorInfo* mappings,
+      std::map<int, base::MemoryMappedFile::Region>* regions) override;
+  void OverrideWebkitPrefs(content::RenderViewHost* rvh,
+                           content::WebPreferences* web_prefs) override;
+#if defined(VIDEO_HOLE)
+  content::ExternalVideoSurfaceContainer*
+  OverrideCreateExternalVideoSurfaceContainer(
+      content::WebContents* web_contents) override;
+#endif
+
+ private:
+  // Android WebView currently has a single global (non-off-the-record) browser
+  // context.
+  scoped_ptr<AwBrowserContext> browser_context_;
+  scoped_ptr<AwWebPreferencesPopulater> preferences_populater_;
+
+  JniDependencyFactory* native_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwContentBrowserClient);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_
diff --git a/android_webview/browser/aw_contents_client_bridge_base.cc b/android_webview/browser/aw_contents_client_bridge_base.cc
new file mode 100644
index 0000000..4888a1ee
--- /dev/null
+++ b/android_webview/browser/aw_contents_client_bridge_base.cc
@@ -0,0 +1,71 @@
+// 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 "android_webview/browser/aw_contents_client_bridge_base.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
+
+using content::BrowserThread;
+using content::WebContents;
+
+namespace android_webview {
+
+namespace {
+
+const void* kAwContentsClientBridgeBase = &kAwContentsClientBridgeBase;
+
+// This class is invented so that the UserData registry that we inject the
+// AwContentsClientBridgeBase object does not own and destroy it.
+class UserData : public base::SupportsUserData::Data {
+ public:
+  static AwContentsClientBridgeBase* GetContents(
+      content::WebContents* web_contents) {
+    if (!web_contents)
+      return NULL;
+    UserData* data = static_cast<UserData*>(
+        web_contents->GetUserData(kAwContentsClientBridgeBase));
+    return data ? data->contents_ : NULL;
+  }
+
+  explicit UserData(AwContentsClientBridgeBase* ptr) : contents_(ptr) {}
+ private:
+  AwContentsClientBridgeBase* contents_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserData);
+};
+
+} // namespace
+
+// static
+void AwContentsClientBridgeBase::Associate(
+    WebContents* web_contents,
+    AwContentsClientBridgeBase* handler) {
+  web_contents->SetUserData(kAwContentsClientBridgeBase,
+                            new UserData(handler));
+}
+
+// static
+AwContentsClientBridgeBase* AwContentsClientBridgeBase::FromWebContents(
+    WebContents* web_contents) {
+  return UserData::GetContents(web_contents);
+}
+
+// static
+AwContentsClientBridgeBase* AwContentsClientBridgeBase::FromID(
+    int render_process_id,
+    int render_frame_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  content::RenderFrameHost* rfh =
+      content::RenderFrameHost::FromID(render_process_id, render_frame_id);
+  content::WebContents* web_contents =
+      content::WebContents::FromRenderFrameHost(rfh);
+  return UserData::GetContents(web_contents);
+}
+
+AwContentsClientBridgeBase::~AwContentsClientBridgeBase() {
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_contents_client_bridge_base.h b/android_webview/browser/aw_contents_client_bridge_base.h
new file mode 100644
index 0000000..9cd9206
--- /dev/null
+++ b/android_webview/browser/aw_contents_client_bridge_base.h
@@ -0,0 +1,69 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_CLIENT_BRIDGE_BASE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_CLIENT_BRIDGE_BASE_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/supports_user_data.h"
+#include "content/public/browser/javascript_dialog_manager.h"
+
+class GURL;
+
+namespace content {
+class ClientCertificateDelegate;
+class WebContents;
+}
+
+namespace net {
+class SSLCertRequestInfo;
+class X509Certificate;
+}
+
+namespace android_webview {
+
+// browser/ layer interface for AwContensClientBridge, as DEPS prevents this
+// layer from depending on native/ where the implementation lives. The
+// implementor of the base class plumbs the request to the Java side and
+// eventually to the webviewclient. This layering hides the details of
+// native/ from browser/ layer.
+class AwContentsClientBridgeBase {
+ public:
+  // Adds the handler to the UserData registry.
+  static void Associate(content::WebContents* web_contents,
+                        AwContentsClientBridgeBase* handler);
+  static AwContentsClientBridgeBase* FromWebContents(
+      content::WebContents* web_contents);
+  static AwContentsClientBridgeBase* FromID(int render_process_id,
+                                            int render_frame_id);
+
+  virtual ~AwContentsClientBridgeBase();
+
+  virtual void AllowCertificateError(int cert_error,
+                                     net::X509Certificate* cert,
+                                     const GURL& request_url,
+                                     const base::Callback<void(bool)>& callback,
+                                     bool* cancel_request) = 0;
+  virtual void SelectClientCertificate(
+      net::SSLCertRequestInfo* cert_request_info,
+      scoped_ptr<content::ClientCertificateDelegate> delegate) = 0;
+
+  virtual void RunJavaScriptDialog(
+      content::JavaScriptMessageType message_type,
+      const GURL& origin_url,
+      const base::string16& message_text,
+      const base::string16& default_prompt_text,
+      const content::JavaScriptDialogManager::DialogClosedCallback& callback)
+      = 0;
+
+  virtual void RunBeforeUnloadDialog(
+      const GURL& origin_url,
+      const base::string16& message_text,
+      const content::JavaScriptDialogManager::DialogClosedCallback& callback)
+      = 0;
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_CLIENT_BRIDGE_BASE_H_
diff --git a/android_webview/browser/aw_contents_io_thread_client.h b/android_webview/browser/aw_contents_io_thread_client.h
new file mode 100644
index 0000000..e2409761
--- /dev/null
+++ b/android_webview/browser/aw_contents_io_thread_client.h
@@ -0,0 +1,118 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_IO_THREAD_CLIENT_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_IO_THREAD_CLIENT_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+
+class GURL;
+
+namespace net {
+class HttpResponseHeaders;
+class URLRequest;
+}
+
+namespace android_webview {
+
+class AwWebResourceResponse;
+
+// This class provides a means of calling Java methods on an instance that has
+// a 1:1 relationship with a WebContents instance directly from the IO thread.
+//
+// Specifically this is used to associate URLRequests with the WebContents that
+// the URLRequest is made for.
+//
+// The native class is intended to be a short-lived handle that pins the
+// Java-side instance. It is preferable to use the static getter methods to
+// obtain a new instance of the class rather than holding on to one for
+// prolonged periods of time (see note for more details).
+//
+// Note: The native AwContentsIoThreadClient instance has a Global ref to
+// the Java object. By keeping the native AwContentsIoThreadClient
+// instance alive you're also prolonging the lifetime of the Java instance, so
+// don't keep a AwContentsIoThreadClient if you don't need to.
+class AwContentsIoThreadClient {
+ public:
+  // Corresponds to WebSettings cache mode constants.
+  enum CacheMode {
+    LOAD_DEFAULT = -1,
+    LOAD_NORMAL = 0,
+    LOAD_CACHE_ELSE_NETWORK = 1,
+    LOAD_NO_CACHE = 2,
+    LOAD_CACHE_ONLY = 3,
+  };
+
+  virtual ~AwContentsIoThreadClient() {}
+
+  // Returns whether this is a new pop up that is still waiting for association
+  // with the java counter part.
+  virtual bool PendingAssociation() const = 0;
+
+  // Retrieve CacheMode setting value of this AwContents.
+  // This method is called on the IO thread only.
+  virtual CacheMode GetCacheMode() const = 0;
+
+  // This will attempt to fetch the AwContentsIoThreadClient for the given
+  // |render_process_id|, |render_frame_id| pair.
+  // This method can be called from any thread.
+  // An empty scoped_ptr is a valid return value.
+  static scoped_ptr<AwContentsIoThreadClient> FromID(int render_process_id,
+                                                     int render_frame_id);
+
+  // Called on the IO thread when a subframe is created.
+  static void SubFrameCreated(int render_process_id,
+                              int parent_render_frame_id,
+                              int child_render_frame_id);
+
+  // This method is called on the IO thread only.
+  virtual scoped_ptr<AwWebResourceResponse> ShouldInterceptRequest(
+      const net::URLRequest* request) = 0;
+
+  // Retrieve the AllowContentAccess setting value of this AwContents.
+  // This method is called on the IO thread only.
+  virtual bool ShouldBlockContentUrls() const = 0;
+
+  // Retrieve the AllowFileAccess setting value of this AwContents.
+  // This method is called on the IO thread only.
+  virtual bool ShouldBlockFileUrls() const = 0;
+
+  // Retrieve the BlockNetworkLoads setting value of this AwContents.
+  // This method is called on the IO thread only.
+  virtual bool ShouldBlockNetworkLoads() const = 0;
+
+  // Retrieve the AcceptThirdPartyCookies setting value of this AwContents.
+  virtual bool ShouldAcceptThirdPartyCookies() const = 0;
+
+  // Called when ResourceDispathcerHost detects a download request.
+  // The download is already cancelled when this is called, since
+  // relevant for DownloadListener is already extracted.
+  virtual void NewDownload(const GURL& url,
+                           const std::string& user_agent,
+                           const std::string& content_disposition,
+                           const std::string& mime_type,
+                           int64 content_length) = 0;
+
+  // Called when a new login request is detected. See the documentation for
+  // WebViewClient.onReceivedLoginRequest for arguments. Note that |account|
+  // may be empty.
+  virtual void NewLoginRequest(const std::string& realm,
+                               const std::string& account,
+                               const std::string& args) = 0;
+
+  // Called when a resource loading error has occured (e.g. an I/O error,
+  // host name lookup failure etc.)
+  virtual void OnReceivedError(const net::URLRequest* request) = 0;
+
+  // Called when a response from the server is received with status code >= 400.
+  virtual void OnReceivedHttpError(
+      const net::URLRequest* request,
+      const net::HttpResponseHeaders* response_headers) = 0;
+};
+
+} // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_IO_THREAD_CLIENT_H_
diff --git a/android_webview/browser/aw_cookie_access_policy.cc b/android_webview/browser/aw_cookie_access_policy.cc
new file mode 100644
index 0000000..242abca
--- /dev/null
+++ b/android_webview/browser/aw_cookie_access_policy.cc
@@ -0,0 +1,145 @@
+// 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 "android_webview/browser/aw_cookie_access_policy.h"
+
+#include "android_webview/browser/aw_contents_io_thread_client.h"
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/resource_request_info.h"
+#include "net/base/net_errors.h"
+
+using base::AutoLock;
+using content::BrowserThread;
+using content::ResourceRequestInfo;
+using net::StaticCookiePolicy;
+
+namespace android_webview {
+
+namespace {
+base::LazyInstance<AwCookieAccessPolicy>::Leaky g_lazy_instance;
+}  // namespace
+
+AwCookieAccessPolicy::~AwCookieAccessPolicy() {
+}
+
+AwCookieAccessPolicy::AwCookieAccessPolicy()
+    : accept_cookies_(true) {
+}
+
+AwCookieAccessPolicy* AwCookieAccessPolicy::GetInstance() {
+  return g_lazy_instance.Pointer();
+}
+
+bool AwCookieAccessPolicy::GetShouldAcceptCookies() {
+  AutoLock lock(lock_);
+  return accept_cookies_;
+}
+
+void AwCookieAccessPolicy::SetShouldAcceptCookies(bool allow) {
+  AutoLock lock(lock_);
+  accept_cookies_ = allow;
+}
+
+bool AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies(
+    int render_process_id,
+    int render_frame_id) {
+  scoped_ptr<AwContentsIoThreadClient> io_thread_client =
+      AwContentsIoThreadClient::FromID(render_process_id, render_frame_id);
+  if (!io_thread_client) {
+    return false;
+  }
+  return io_thread_client->ShouldAcceptThirdPartyCookies();
+}
+
+bool AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies(
+    const net::URLRequest& request) {
+  const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request);
+  if (!info) {
+    return false;
+  }
+  return GetShouldAcceptThirdPartyCookies(info->GetChildID(),
+                                          info->GetRenderFrameID());
+}
+
+bool AwCookieAccessPolicy::OnCanGetCookies(const net::URLRequest& request,
+                                           const net::CookieList& cookie_list) {
+  bool global = GetShouldAcceptCookies();
+  bool thirdParty = GetShouldAcceptThirdPartyCookies(request);
+  return AwStaticCookiePolicy(global, thirdParty)
+      .AllowGet(request.url(), request.first_party_for_cookies());
+}
+
+bool AwCookieAccessPolicy::OnCanSetCookie(const net::URLRequest& request,
+                                          const std::string& cookie_line,
+                                          net::CookieOptions* options) {
+  bool global = GetShouldAcceptCookies();
+  bool thirdParty = GetShouldAcceptThirdPartyCookies(request);
+  return AwStaticCookiePolicy(global, thirdParty)
+      .AllowSet(request.url(), request.first_party_for_cookies());
+}
+
+bool AwCookieAccessPolicy::AllowGetCookie(const GURL& url,
+                                          const GURL& first_party,
+                                          const net::CookieList& cookie_list,
+                                          content::ResourceContext* context,
+                                          int render_process_id,
+                                          int render_frame_id) {
+  bool global = GetShouldAcceptCookies();
+  bool thirdParty =
+      GetShouldAcceptThirdPartyCookies(render_process_id, render_frame_id);
+  return AwStaticCookiePolicy(global, thirdParty).AllowGet(url, first_party);
+}
+
+bool AwCookieAccessPolicy::AllowSetCookie(const GURL& url,
+                                          const GURL& first_party,
+                                          const std::string& cookie_line,
+                                          content::ResourceContext* context,
+                                          int render_process_id,
+                                          int render_frame_id,
+                                          net::CookieOptions* options) {
+  bool global = GetShouldAcceptCookies();
+  bool thirdParty =
+      GetShouldAcceptThirdPartyCookies(render_process_id, render_frame_id);
+  return AwStaticCookiePolicy(global, thirdParty).AllowSet(url, first_party);
+}
+
+AwStaticCookiePolicy::AwStaticCookiePolicy(bool accept_cookies,
+                                           bool accept_third_party_cookies)
+    : accept_cookies_(accept_cookies),
+      accept_third_party_cookies_(accept_third_party_cookies) {
+}
+
+StaticCookiePolicy::Type AwStaticCookiePolicy::GetPolicy(const GURL& url)
+    const {
+  // File URLs are a special case. We want file URLs to be able to set cookies
+  // but (for the purpose of cookies) Chrome considers different file URLs to
+  // come from different origins so we use the 'allow all' cookie policy for
+  // file URLs.
+  bool isFile = url.SchemeIsFile();
+  if (!accept_cookies()) {
+    return StaticCookiePolicy::BLOCK_ALL_COOKIES;
+  }
+  if (accept_third_party_cookies() || isFile) {
+    return StaticCookiePolicy::ALLOW_ALL_COOKIES;
+  }
+  return StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES;
+}
+
+bool AwStaticCookiePolicy::AllowSet(const GURL& url,
+                                    const GURL& first_party) const {
+
+  return StaticCookiePolicy(GetPolicy(url)).CanSetCookie(url, first_party) ==
+         net::OK;
+}
+
+bool AwStaticCookiePolicy::AllowGet(const GURL& url,
+                                    const GURL& first_party) const {
+  return StaticCookiePolicy(GetPolicy(url)).CanGetCookies(url, first_party) ==
+         net::OK;
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_cookie_access_policy.h b/android_webview/browser/aw_cookie_access_policy.h
new file mode 100644
index 0000000..a2de037
--- /dev/null
+++ b/android_webview/browser/aw_cookie_access_policy.h
@@ -0,0 +1,112 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_COOKIE_ACCESS_POLICY_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_COOKIE_ACCESS_POLICY_H_
+
+#include "base/basictypes.h"
+#include "base/lazy_instance.h"
+#include "base/synchronization/lock.h"
+#include "net/base/static_cookie_policy.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/url_request/url_request.h"
+
+namespace content {
+class ResourceContext;
+}
+
+namespace net {
+class CookieOptions;
+}
+
+class GURL;
+
+namespace android_webview {
+
+// Manages the cookie access (both setting and getting) policy for WebView.
+// Currently we don't distinguish between sources (i.e. network vs. JavaScript)
+// or between reading vs. writing cookies.
+class AwCookieAccessPolicy {
+ public:
+  static AwCookieAccessPolicy* GetInstance();
+
+  // Can we read/write any cookies?
+  bool GetShouldAcceptCookies();
+  void SetShouldAcceptCookies(bool allow);
+
+  // Can we read/write third party cookies?
+  bool GetShouldAcceptThirdPartyCookies(int render_process_id,
+                                        int render_frame_id);
+  bool GetShouldAcceptThirdPartyCookies(const net::URLRequest& request);
+
+  // These are the functions called when operating over cookies from the
+  // network. See NetworkDelegate for further descriptions.
+  bool OnCanGetCookies(const net::URLRequest& request,
+                       const net::CookieList& cookie_list);
+  bool OnCanSetCookie(const net::URLRequest& request,
+                      const std::string& cookie_line,
+                      net::CookieOptions* options);
+
+  // These are the functions called when operating over cookies from the
+  // renderer. See ContentBrowserClient for further descriptions.
+  bool AllowGetCookie(const GURL& url,
+                      const GURL& first_party,
+                      const net::CookieList& cookie_list,
+                      content::ResourceContext* context,
+                      int render_process_id,
+                      int render_frame_id);
+  bool AllowSetCookie(const GURL& url,
+                      const GURL& first_party,
+                      const std::string& cookie_line,
+                      content::ResourceContext* context,
+                      int render_process_id,
+                      int render_frame_id,
+                      net::CookieOptions* options);
+
+ private:
+  friend struct base::DefaultLazyInstanceTraits<AwCookieAccessPolicy>;
+
+  AwCookieAccessPolicy();
+  ~AwCookieAccessPolicy();
+  bool accept_cookies_;
+  base::Lock lock_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwCookieAccessPolicy);
+};
+
+class AwStaticCookiePolicy {
+ public:
+  AwStaticCookiePolicy(bool allow_global_access,
+                       bool allow_third_party_access);
+
+  bool accept_cookies() const {
+    return accept_cookies_;
+  }
+
+  bool accept_third_party_cookies() const {
+    return accept_third_party_cookies_;
+  }
+
+  bool AllowGet(const GURL& url, const GURL& first_party) const;
+  bool AllowSet(const GURL& url, const GURL& first_party) const;
+
+ private:
+  const bool accept_cookies_;
+  const bool accept_third_party_cookies_;
+
+  // We have two bits of state but only three different cases:
+  // If !ShouldAcceptCookies
+  //    then reject all cookies.
+  // If ShouldAcceptCookies and !ShouldAcceptThirdPartyCookies
+  //    then reject third party.
+  // If ShouldAcceptCookies and ShouldAcceptThirdPartyCookies
+  //    then allow all cookies.
+  net::StaticCookiePolicy::Type GetPolicy(const GURL& url) const;
+
+  DISALLOW_COPY_AND_ASSIGN(AwStaticCookiePolicy);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_COOKIE_ACCESS_POLICY_H_
diff --git a/android_webview/browser/aw_dev_tools_discovery_provider.cc b/android_webview/browser/aw_dev_tools_discovery_provider.cc
new file mode 100644
index 0000000..fe1e61e
--- /dev/null
+++ b/android_webview/browser/aw_dev_tools_discovery_provider.cc
@@ -0,0 +1,89 @@
+// Copyright 2015 The Chromium Authors. 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/aw_dev_tools_discovery_provider.h"
+
+#include "android_webview/browser/browser_view_renderer.h"
+#include "base/json/json_writer.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "components/devtools_discovery/basic_target_descriptor.h"
+#include "components/devtools_discovery/devtools_discovery_manager.h"
+#include "content/public/browser/devtools_agent_host.h"
+#include "content/public/browser/web_contents.h"
+
+using content::DevToolsAgentHost;
+using content::WebContents;
+
+namespace {
+
+std::string GetViewDescription(WebContents* web_contents) {
+  android_webview::BrowserViewRenderer* bvr =
+      android_webview::BrowserViewRenderer::FromWebContents(web_contents);
+  if (!bvr) return "";
+  base::DictionaryValue description;
+  description.SetBoolean("attached", bvr->attached_to_window());
+  description.SetBoolean("visible", bvr->IsVisible());
+  gfx::Rect screen_rect = bvr->GetScreenRect();
+  description.SetInteger("screenX", screen_rect.x());
+  description.SetInteger("screenY", screen_rect.y());
+  description.SetBoolean("empty", screen_rect.size().IsEmpty());
+  if (!screen_rect.size().IsEmpty()) {
+    description.SetInteger("width", screen_rect.width());
+    description.SetInteger("height", screen_rect.height());
+  }
+  std::string json;
+  base::JSONWriter::Write(description, &json);
+  return json;
+}
+
+class TargetDescriptor : public devtools_discovery::BasicTargetDescriptor {
+ public:
+  explicit TargetDescriptor(scoped_refptr<DevToolsAgentHost> agent_host);
+
+  // devtools_discovery::BasicTargetDescriptor overrides.
+  std::string GetDescription() const override { return description_; }
+
+ private:
+  std::string description_;
+
+  DISALLOW_COPY_AND_ASSIGN(TargetDescriptor);
+};
+
+TargetDescriptor::TargetDescriptor(scoped_refptr<DevToolsAgentHost> agent_host)
+    : BasicTargetDescriptor(agent_host) {
+  if (WebContents* web_contents = agent_host->GetWebContents())
+    description_ = GetViewDescription(web_contents);
+}
+
+}  // namespace
+
+namespace android_webview {
+
+// static
+void AwDevToolsDiscoveryProvider::Install() {
+  devtools_discovery::DevToolsDiscoveryManager* discovery_manager =
+      devtools_discovery::DevToolsDiscoveryManager::GetInstance();
+  discovery_manager->AddProvider(
+      make_scoped_ptr(new AwDevToolsDiscoveryProvider()));
+}
+
+AwDevToolsDiscoveryProvider::AwDevToolsDiscoveryProvider() {
+}
+
+AwDevToolsDiscoveryProvider::~AwDevToolsDiscoveryProvider() {
+}
+
+devtools_discovery::DevToolsTargetDescriptor::List
+AwDevToolsDiscoveryProvider::GetDescriptors() {
+  DevToolsAgentHost::List agent_hosts = DevToolsAgentHost::GetOrCreateAll();
+  devtools_discovery::DevToolsTargetDescriptor::List result;
+  result.reserve(agent_hosts.size());
+  for (const auto& agent_host : agent_hosts)
+    result.push_back(new TargetDescriptor(agent_host));
+  return result;
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_dev_tools_discovery_provider.h b/android_webview/browser/aw_dev_tools_discovery_provider.h
new file mode 100644
index 0000000..e679e0f
--- /dev/null
+++ b/android_webview/browser/aw_dev_tools_discovery_provider.h
@@ -0,0 +1,31 @@
+// Copyright 2015 The Chromium Authors. 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_AW_DEV_TOOLS_DISCOVERY_PROVIDER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_DEV_TOOLS_DISCOVERY_PROVIDER_H_
+
+#include "components/devtools_discovery/devtools_discovery_manager.h"
+
+namespace android_webview {
+
+class AwDevToolsDiscoveryProvider :
+    public devtools_discovery::DevToolsDiscoveryManager::Provider {
+ public:
+  // Installs provider to devtools_discovery.
+  static void Install();
+
+  ~AwDevToolsDiscoveryProvider() override;
+
+  // devtools_discovery::DevToolsDiscoveryManager::Provider implementation.
+  devtools_discovery::DevToolsTargetDescriptor::List GetDescriptors() override;
+
+ private:
+  AwDevToolsDiscoveryProvider();
+
+  DISALLOW_COPY_AND_ASSIGN(AwDevToolsDiscoveryProvider);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_DEV_TOOLS_DISCOVERY_PROVIDER_H_
diff --git a/android_webview/browser/aw_download_manager_delegate.cc b/android_webview/browser/aw_download_manager_delegate.cc
new file mode 100644
index 0000000..cf685f7
--- /dev/null
+++ b/android_webview/browser/aw_download_manager_delegate.cc
@@ -0,0 +1,49 @@
+// 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 "android_webview/browser/aw_download_manager_delegate.h"
+
+#include "base/files/file_path.h"
+#include "content/public/browser/download_danger_type.h"
+#include "content/public/browser/download_item.h"
+
+
+namespace android_webview {
+
+AwDownloadManagerDelegate::~AwDownloadManagerDelegate() {}
+
+bool AwDownloadManagerDelegate::DetermineDownloadTarget(
+    content::DownloadItem* item,
+    const content::DownloadTargetCallback& callback) {
+  // Note this cancel is independent of the URLRequest cancel in
+  // AwResourceDispatcherHostDelegate::DownloadStarting. The request
+  // could have already finished by the time DownloadStarting is called.
+  callback.Run(base::FilePath() /* Empty file path for cancel */,
+               content::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+               content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+               base::FilePath());
+  return true;
+}
+
+bool AwDownloadManagerDelegate::ShouldCompleteDownload(
+    content::DownloadItem* item,
+    const base::Closure& complete_callback) {
+  NOTREACHED();
+  return true;
+}
+
+bool AwDownloadManagerDelegate::ShouldOpenDownload(
+    content::DownloadItem* item,
+    const content::DownloadOpenDelayedCallback& callback) {
+  NOTREACHED();
+  return true;
+}
+
+void AwDownloadManagerDelegate::GetNextId(
+    const content::DownloadIdCallback& callback) {
+  static uint32 next_id = content::DownloadItem::kInvalidId + 1;
+  callback.Run(next_id++);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_download_manager_delegate.h b/android_webview/browser/aw_download_manager_delegate.h
new file mode 100644
index 0000000..36b3d6b
--- /dev/null
+++ b/android_webview/browser/aw_download_manager_delegate.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 ANDROID_WEBVIEW_BROWSER_AW_DOWNLOAD_MANAGER_DELEGATE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_DOWNLOAD_MANAGER_DELEGATE_H_
+
+#include "content/public/browser/download_manager_delegate.h"
+
+namespace android_webview {
+
+// Android WebView does not use Chromium downloads, so implement methods here to
+// unconditionally cancel the download.
+class AwDownloadManagerDelegate : public content::DownloadManagerDelegate {
+ public:
+  ~AwDownloadManagerDelegate() override;
+
+  // content::DownloadManagerDelegate implementation.
+  bool DetermineDownloadTarget(
+      content::DownloadItem* item,
+      const content::DownloadTargetCallback& callback) override;
+  bool ShouldCompleteDownload(content::DownloadItem* item,
+                              const base::Closure& complete_callback) override;
+  bool ShouldOpenDownload(
+      content::DownloadItem* item,
+      const content::DownloadOpenDelayedCallback& callback) override;
+  void GetNextId(const content::DownloadIdCallback& callback) override;
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_DOWNLOAD_MANAGER_DELEGATE_H_
diff --git a/android_webview/browser/aw_form_database_service.cc b/android_webview/browser/aw_form_database_service.cc
new file mode 100644
index 0000000..c8b98bb
--- /dev/null
+++ b/android_webview/browser/aw_form_database_service.cc
@@ -0,0 +1,125 @@
+// 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 "android_webview/browser/aw_form_database_service.h"
+
+#include "base/logging.h"
+#include "base/synchronization/waitable_event.h"
+#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/webdata/common/webdata_constants.h"
+#include "content/public/browser/browser_thread.h"
+
+using base::WaitableEvent;
+using content::BrowserThread;
+
+namespace {
+
+// Callback to handle database error. It seems chrome uses this to
+// display an error dialog box only.
+void DatabaseErrorCallback(sql::InitStatus status) {
+  LOG(WARNING) << "initializing autocomplete database failed";
+}
+
+}  // namespace
+
+namespace android_webview {
+
+AwFormDatabaseService::AwFormDatabaseService(const base::FilePath path) {
+  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  web_database_ = new WebDatabaseService(path.Append(kWebDataFilename),
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB));
+  web_database_->AddTable(make_scoped_ptr(new autofill::AutofillTable));
+  web_database_->LoadDatabase();
+
+  autofill_data_ = new autofill::AutofillWebDataService(
+      web_database_,
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
+      base::Bind(&DatabaseErrorCallback));
+  autofill_data_->Init();
+}
+
+AwFormDatabaseService::~AwFormDatabaseService() {
+  Shutdown();
+}
+
+void AwFormDatabaseService::Shutdown() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(result_map_.empty());
+  // TODO(sgurun) we don't run into this logic right now,
+  // but if we do, then we need to implement cancellation
+  // of pending queries.
+  autofill_data_->ShutdownOnUIThread();
+  web_database_->ShutdownDatabase();
+}
+
+scoped_refptr<autofill::AutofillWebDataService>
+AwFormDatabaseService::get_autofill_webdata_service() {
+  return autofill_data_;
+}
+
+void AwFormDatabaseService::ClearFormData() {
+  BrowserThread::PostTask(
+      BrowserThread::DB,
+      FROM_HERE,
+      base::Bind(&AwFormDatabaseService::ClearFormDataImpl,
+                 base::Unretained(this)));
+}
+
+void AwFormDatabaseService::ClearFormDataImpl() {
+  base::Time begin;
+  base::Time end = base::Time::Max();
+  autofill_data_->RemoveFormElementsAddedBetween(begin, end);
+  autofill_data_->RemoveAutofillDataModifiedBetween(begin, end);
+}
+
+bool AwFormDatabaseService::HasFormData() {
+  WaitableEvent completion(false, false);
+  bool result = false;
+  BrowserThread::PostTask(
+      BrowserThread::DB,
+      FROM_HERE,
+      base::Bind(&AwFormDatabaseService::HasFormDataImpl,
+                 base::Unretained(this),
+                 &completion,
+                 &result));
+  completion.Wait();
+  return result;
+}
+
+void AwFormDatabaseService::HasFormDataImpl(
+    WaitableEvent* completion,
+    bool* result) {
+  WebDataServiceBase::Handle pending_query_handle =
+      autofill_data_->HasFormElements(this);
+  PendingQuery query;
+  query.result = result;
+  query.completion = completion;
+  result_map_[pending_query_handle] = query;
+}
+
+void AwFormDatabaseService::OnWebDataServiceRequestDone(
+    WebDataServiceBase::Handle h,
+    const WDTypedResult* result) {
+
+  DCHECK_CURRENTLY_ON(BrowserThread::DB);
+  bool has_form_data = false;
+  if (result) {
+    DCHECK_EQ(AUTOFILL_VALUE_RESULT, result->GetType());
+    const WDResult<bool>* autofill_result =
+        static_cast<const WDResult<bool>*>(result);
+    has_form_data = autofill_result->GetValue();
+  }
+  QueryMap::const_iterator it = result_map_.find(h);
+  if (it == result_map_.end()) {
+    LOG(WARNING) << "Received unexpected callback from web data service";
+    return;
+  }
+  *(it->second.result) = has_form_data;
+  it->second.completion->Signal();
+  result_map_.erase(h);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_form_database_service.h b/android_webview/browser/aw_form_database_service.h
new file mode 100644
index 0000000..857b23a
--- /dev/null
+++ b/android_webview/browser/aw_form_database_service.h
@@ -0,0 +1,66 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_FORM_DATABASE_SERVICE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_FORM_DATABASE_SERVICE_H_
+
+#include "base/basictypes.h"
+#include "base/files/file_path.h"
+#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
+#include "components/webdata/common/web_data_service_consumer.h"
+#include "components/webdata/common/web_database_service.h"
+
+namespace base {
+class WaitableEvent;
+};
+
+namespace android_webview {
+
+// Handles the database operations necessary to implement the autocomplete
+// functionality. This includes creating and initializing the components that
+// handle the database backend, and providing a synchronous interface when
+// needed (the chromium database components have an async. interface).
+class AwFormDatabaseService : public WebDataServiceConsumer {
+ public:
+  AwFormDatabaseService(const base::FilePath path);
+
+  ~AwFormDatabaseService() override;
+
+  void Shutdown();
+
+  // Returns whether the database has any data stored. May do
+  // IO access and block.
+  bool HasFormData();
+
+  // Clear any saved form data. Executes asynchronously.
+  void ClearFormData();
+
+  scoped_refptr<autofill::AutofillWebDataService>
+      get_autofill_webdata_service();
+
+  // WebDataServiceConsumer implementation.
+  void OnWebDataServiceRequestDone(WebDataServiceBase::Handle h,
+                                   const WDTypedResult* result) override;
+
+ private:
+  struct PendingQuery {
+    bool* result;
+    base::WaitableEvent* completion;
+  };
+  typedef std::map<WebDataServiceBase::Handle, PendingQuery> QueryMap;
+
+  void ClearFormDataImpl();
+  void HasFormDataImpl(base::WaitableEvent* completion, bool* result);
+
+  QueryMap result_map_;
+
+  scoped_refptr<autofill::AutofillWebDataService> autofill_data_;
+  scoped_refptr<WebDatabaseService> web_database_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwFormDatabaseService);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_FORM_DATABASE_SERVICE_H_
diff --git a/android_webview/browser/aw_form_database_service_unittest.cc b/android_webview/browser/aw_form_database_service_unittest.cc
new file mode 100644
index 0000000..34f4449
--- /dev/null
+++ b/android_webview/browser/aw_form_database_service_unittest.cc
@@ -0,0 +1,73 @@
+// 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 <vector>
+
+#include "android_webview/browser/aw_form_database_service.h"
+#include "base/android/jni_android.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
+#include "components/autofill/core/common/form_field_data.h"
+#include "content/public/test/test_browser_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/l10n/l10n_util_android.h"
+
+using autofill::AutofillWebDataService;
+using autofill::FormFieldData;
+using base::android::AttachCurrentThread;
+using content::BrowserThread;
+using testing::Test;
+
+namespace android_webview {
+
+class AwFormDatabaseServiceTest : public Test {
+ public:
+  AwFormDatabaseServiceTest()
+      : ui_thread_(BrowserThread::UI, &message_loop_),
+        db_thread_(BrowserThread::DB) {
+    db_thread_.Start();
+  }
+
+ protected:
+  void SetUp() override {
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+    env_ = AttachCurrentThread();
+    ASSERT_TRUE(env_ != NULL);
+    ASSERT_TRUE(l10n_util::RegisterLocalizationUtil(env_));
+
+    service_.reset(new AwFormDatabaseService(temp_dir_.path()));
+  }
+
+  void TearDown() override { service_->Shutdown(); }
+
+  // The path to the temporary directory used for the test operations.
+  base::ScopedTempDir temp_dir_;
+  // A message loop for UI thread.
+  base::MessageLoop message_loop_;
+  content::TestBrowserThread ui_thread_;
+  content::TestBrowserThread db_thread_;
+  JNIEnv* env_;
+
+  scoped_ptr<AwFormDatabaseService> service_;
+};
+
+// Disabling this test until we know why it crashes.
+// TODO(sgurun): See http://crbug.com/287726 for details.
+TEST_F(AwFormDatabaseServiceTest, DISABLED_HasAndClearFormData) {
+  EXPECT_FALSE(service_->HasFormData());
+  std::vector<FormFieldData> fields;
+  FormFieldData field;
+  field.name = base::ASCIIToUTF16("foo");
+  field.value = base::ASCIIToUTF16("bar");
+  fields.push_back(field);
+  service_->get_autofill_webdata_service()->AddFormFields(fields);
+  EXPECT_TRUE(service_->HasFormData());
+  service_->ClearFormData();
+  EXPECT_FALSE(service_->HasFormData());
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_gl_surface.cc b/android_webview/browser/aw_gl_surface.cc
new file mode 100644
index 0000000..3f4d852
--- /dev/null
+++ b/android_webview/browser/aw_gl_surface.cc
@@ -0,0 +1,44 @@
+// 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 "android_webview/browser/aw_gl_surface.h"
+
+namespace android_webview {
+
+AwGLSurface::AwGLSurface() : fbo_(0) {}
+
+AwGLSurface::~AwGLSurface() {}
+
+void AwGLSurface::Destroy() {
+}
+
+bool AwGLSurface::IsOffscreen() {
+  return false;
+}
+
+unsigned int AwGLSurface::GetBackingFrameBufferObject() {
+  return fbo_;
+}
+
+gfx::SwapResult AwGLSurface::SwapBuffers() {
+  return gfx::SwapResult::SWAP_ACK;
+}
+
+gfx::Size AwGLSurface::GetSize() {
+  return gfx::Size(1, 1);
+}
+
+void* AwGLSurface::GetHandle() {
+  return NULL;
+}
+
+void* AwGLSurface::GetDisplay() {
+  return NULL;
+}
+
+void AwGLSurface::SetBackingFrameBufferObject(unsigned int fbo) {
+  fbo_ = fbo;
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_gl_surface.h b/android_webview/browser/aw_gl_surface.h
new file mode 100644
index 0000000..36ad962
--- /dev/null
+++ b/android_webview/browser/aw_gl_surface.h
@@ -0,0 +1,41 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
+
+#include "ui/gl/gl_surface.h"
+
+namespace android_webview {
+
+// This surface is used to represent the underlying surface provided by the App
+// inside a hardware draw. Note that offscreen contexts will not be using this
+// GLSurface.
+class GL_EXPORT AwGLSurface : public gfx::GLSurface {
+ public:
+  AwGLSurface();
+
+  // Implement GLSurface.
+  void Destroy() override;
+  bool IsOffscreen() override;
+  unsigned int GetBackingFrameBufferObject() override;
+  gfx::SwapResult SwapBuffers() override;
+  gfx::Size GetSize() override;
+  void* GetHandle() override;
+  void* GetDisplay() override;
+
+  void SetBackingFrameBufferObject(unsigned int fbo);
+
+ protected:
+  ~AwGLSurface() override;
+
+ private:
+  unsigned int fbo_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwGLSurface);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_GL_SURFACE_H_
diff --git a/android_webview/browser/aw_http_auth_handler_base.cc b/android_webview/browser/aw_http_auth_handler_base.cc
new file mode 100644
index 0000000..0fd5419
--- /dev/null
+++ b/android_webview/browser/aw_http_auth_handler_base.cc
@@ -0,0 +1,12 @@
+// 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 "android_webview/browser/aw_http_auth_handler_base.h"
+
+namespace android_webview {
+
+AwHttpAuthHandlerBase::~AwHttpAuthHandlerBase() {
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_http_auth_handler_base.h b/android_webview/browser/aw_http_auth_handler_base.h
new file mode 100644
index 0000000..e72003b
--- /dev/null
+++ b/android_webview/browser/aw_http_auth_handler_base.h
@@ -0,0 +1,37 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_HTTP_AUTH_HANDLER_BASE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_HTTP_AUTH_HANDLER_BASE_H_
+
+namespace content {
+class WebContents;
+};
+
+namespace net {
+class AuthChallengeInfo;
+};
+
+namespace android_webview {
+
+class AwLoginDelegate;
+
+// browser/ layer interface for AwHttpAuthHandler (which is implemented in the
+// native/ layer as a native version of the Java class of the same name). This
+// allows the browser/ layer to be unaware of JNI/Java shenanigans.
+class AwHttpAuthHandlerBase {
+ public:
+  static AwHttpAuthHandlerBase* Create(AwLoginDelegate* login_delegate,
+                                       net::AuthChallengeInfo* auth_info,
+                                       bool first_auth_attempt);
+  virtual ~AwHttpAuthHandlerBase();
+
+  // Provides an 'escape-hatch' out to Java for the browser/ layer
+  // AwLoginDelegate.
+  virtual bool HandleOnUIThread(content::WebContents*) = 0;
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_HTTP_AUTH_HANDLER_BASE_H_
diff --git a/android_webview/browser/aw_javascript_dialog_manager.cc b/android_webview/browser/aw_javascript_dialog_manager.cc
new file mode 100644
index 0000000..afe9bda
--- /dev/null
+++ b/android_webview/browser/aw_javascript_dialog_manager.cc
@@ -0,0 +1,65 @@
+// 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 "android_webview/browser/aw_javascript_dialog_manager.h"
+
+#include "android_webview/browser/aw_contents_client_bridge_base.h"
+#include "content/public/browser/javascript_dialog_manager.h"
+#include "content/public/browser/web_contents.h"
+
+namespace android_webview {
+
+AwJavaScriptDialogManager::AwJavaScriptDialogManager() {}
+
+AwJavaScriptDialogManager::~AwJavaScriptDialogManager() {}
+
+void AwJavaScriptDialogManager::RunJavaScriptDialog(
+    content::WebContents* web_contents,
+    const GURL& origin_url,
+    const std::string& accept_lang,
+    content::JavaScriptMessageType message_type,
+    const base::string16& message_text,
+    const base::string16& default_prompt_text,
+    const DialogClosedCallback& callback,
+    bool* did_suppress_message) {
+  AwContentsClientBridgeBase* bridge =
+      AwContentsClientBridgeBase::FromWebContents(web_contents);
+  if (!bridge) {
+    callback.Run(false, base::string16());
+    return;
+  }
+
+  bridge->RunJavaScriptDialog(message_type,
+                              origin_url,
+                              message_text,
+                              default_prompt_text,
+                              callback);
+}
+
+void AwJavaScriptDialogManager::RunBeforeUnloadDialog(
+    content::WebContents* web_contents,
+    const base::string16& message_text,
+    bool is_reload,
+    const DialogClosedCallback& callback) {
+  AwContentsClientBridgeBase* bridge =
+      AwContentsClientBridgeBase::FromWebContents(web_contents);
+  if (!bridge) {
+    callback.Run(false, base::string16());
+    return;
+  }
+
+  bridge->RunBeforeUnloadDialog(web_contents->GetURL(),
+                                message_text,
+                                callback);
+}
+
+void AwJavaScriptDialogManager::CancelActiveAndPendingDialogs(
+    content::WebContents* web_contents) {
+}
+
+void AwJavaScriptDialogManager::ResetDialogState(
+    content::WebContents* web_contents) {
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_javascript_dialog_manager.h b/android_webview/browser/aw_javascript_dialog_manager.h
new file mode 100644
index 0000000..1c42542
--- /dev/null
+++ b/android_webview/browser/aw_javascript_dialog_manager.h
@@ -0,0 +1,40 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_JAVASCRIPT_DIALOG_MANAGER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_JAVASCRIPT_DIALOG_MANAGER_H_
+
+#include "content/public/browser/javascript_dialog_manager.h"
+
+namespace android_webview {
+
+class AwJavaScriptDialogManager : public content::JavaScriptDialogManager {
+ public:
+  explicit AwJavaScriptDialogManager();
+  ~AwJavaScriptDialogManager() override;
+
+  // Overridden from content::JavaScriptDialogManager:
+  void RunJavaScriptDialog(content::WebContents* web_contents,
+                           const GURL& origin_url,
+                           const std::string& accept_lang,
+                           content::JavaScriptMessageType message_type,
+                           const base::string16& message_text,
+                           const base::string16& default_prompt_text,
+                           const DialogClosedCallback& callback,
+                           bool* did_suppress_message) override;
+  void RunBeforeUnloadDialog(content::WebContents* web_contents,
+                             const base::string16& message_text,
+                             bool is_reload,
+                             const DialogClosedCallback& callback) override;
+  void CancelActiveAndPendingDialogs(
+      content::WebContents* web_contents) override;
+  void ResetDialogState(content::WebContents* web_contents) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AwJavaScriptDialogManager);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_JAVASCRIPT_DIALOG_MANAGER_H_
diff --git a/android_webview/browser/aw_locale_manager.h b/android_webview/browser/aw_locale_manager.h
new file mode 100644
index 0000000..bdc822a5
--- /dev/null
+++ b/android_webview/browser/aw_locale_manager.h
@@ -0,0 +1,28 @@
+// Copyright 2015 The Chromium Authors. 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_AW_LOCALE_MANAGER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_LOCALE_MANAGER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+
+namespace android_webview {
+
+// Empty base class so this can be destroyed by AwContentBrowserClient.
+class AwLocaleManager {
+ public:
+  AwLocaleManager() {}
+  virtual ~AwLocaleManager() {}
+
+  virtual std::string GetLocale() = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AwLocaleManager);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_LOCALE_MANAGER_H_
diff --git a/android_webview/browser/aw_login_delegate.cc b/android_webview/browser/aw_login_delegate.cc
new file mode 100644
index 0000000..7ce8e70
--- /dev/null
+++ b/android_webview/browser/aw_login_delegate.cc
@@ -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.
+
+#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 "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/resource_dispatcher_host.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/browser/web_contents.h"
+#include "net/base/auth.h"
+#include "net/url_request/url_request.h"
+
+using namespace base::android;
+
+using content::BrowserThread;
+using content::RenderFrameHost;
+using content::ResourceDispatcherHost;
+using content::ResourceRequestInfo;
+using content::WebContents;
+
+namespace {
+const char* kAuthAttemptsKey = "android_webview_auth_attempts";
+
+class UrlRequestAuthAttemptsData : public base::SupportsUserData::Data {
+ public:
+  UrlRequestAuthAttemptsData() : auth_attempts_(0) { }
+  int auth_attempts_;
+};
+
+}  // namespace
+
+namespace android_webview {
+
+AwLoginDelegate::AwLoginDelegate(net::AuthChallengeInfo* auth_info,
+                                 net::URLRequest* request)
+    : auth_info_(auth_info),
+      request_(request),
+      render_process_id_(0),
+      render_frame_id_(0) {
+    ResourceRequestInfo::GetRenderFrameForRequest(
+        request, &render_process_id_, &render_frame_id_);
+
+    UrlRequestAuthAttemptsData* count =
+        static_cast<UrlRequestAuthAttemptsData*>(
+            request->GetUserData(kAuthAttemptsKey));
+
+    if (count == NULL) {
+      count = new UrlRequestAuthAttemptsData();
+      request->SetUserData(kAuthAttemptsKey, count);
+    }
+
+    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+        base::Bind(&AwLoginDelegate::HandleHttpAuthRequestOnUIThread,
+                   this, (count->auth_attempts_ == 0)));
+    count->auth_attempts_++;
+}
+
+AwLoginDelegate::~AwLoginDelegate() {
+  // The Auth handler holds a ref count back on |this| object, so it should be
+  // impossible to reach here while this object still owns an auth handler.
+  DCHECK(!aw_http_auth_handler_);
+}
+
+void AwLoginDelegate::Proceed(const base::string16& user,
+                              const base::string16& password) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+      base::Bind(&AwLoginDelegate::ProceedOnIOThread,
+                 this, user, password));
+}
+
+void AwLoginDelegate::Cancel() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+      base::Bind(&AwLoginDelegate::CancelOnIOThread, this));
+}
+
+void AwLoginDelegate::HandleHttpAuthRequestOnUIThread(
+    bool first_auth_attempt) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  aw_http_auth_handler_.reset(AwHttpAuthHandlerBase::Create(
+      this, auth_info_.get(), first_auth_attempt));
+
+  RenderFrameHost* render_frame_host = RenderFrameHost::FromID(
+      render_process_id_, render_frame_id_);
+  WebContents* web_contents = WebContents::FromRenderFrameHost(
+      render_frame_host);
+  if (!aw_http_auth_handler_->HandleOnUIThread(web_contents)) {
+    Cancel();
+    return;
+  }
+}
+
+void AwLoginDelegate::CancelOnIOThread() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (request_) {
+    request_->CancelAuth();
+    ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request_);
+    request_ = NULL;
+  }
+  DeleteAuthHandlerSoon();
+}
+
+void AwLoginDelegate::ProceedOnIOThread(const base::string16& user,
+                                        const base::string16& password) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (request_) {
+    request_->SetAuth(net::AuthCredentials(user, password));
+    ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request_);
+    request_ = NULL;
+  }
+  DeleteAuthHandlerSoon();
+}
+
+void AwLoginDelegate::OnRequestCancelled() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  request_ = NULL;
+  DeleteAuthHandlerSoon();
+}
+
+void AwLoginDelegate::DeleteAuthHandlerSoon() {
+  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+        base::Bind(&AwLoginDelegate::DeleteAuthHandlerSoon, this));
+    return;
+  }
+  aw_http_auth_handler_.reset();
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_login_delegate.h b/android_webview/browser/aw_login_delegate.h
new file mode 100644
index 0000000..0331c6b5
--- /dev/null
+++ b/android_webview/browser/aw_login_delegate.h
@@ -0,0 +1,51 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_LOGIN_DELEGATE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_LOGIN_DELEGATE_H_
+
+#include "android_webview/browser/aw_http_auth_handler_base.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
+#include "content/public/browser/resource_dispatcher_host_login_delegate.h"
+
+namespace net {
+class AuthChallengeInfo;
+class URLRequest;
+}
+
+namespace android_webview {
+
+class AwLoginDelegate :
+    public content::ResourceDispatcherHostLoginDelegate {
+ public:
+  AwLoginDelegate(net::AuthChallengeInfo* auth_info,
+                  net::URLRequest* request);
+
+  virtual void Proceed(const base::string16& user,
+                       const base::string16& password);
+  virtual void Cancel();
+
+  // from ResourceDispatcherHostLoginDelegate
+  void OnRequestCancelled() override;
+
+ private:
+  ~AwLoginDelegate() override;
+  void HandleHttpAuthRequestOnUIThread(bool first_auth_attempt);
+  void CancelOnIOThread();
+  void ProceedOnIOThread(const base::string16& user,
+                         const base::string16& password);
+  void DeleteAuthHandlerSoon();
+
+  scoped_ptr<AwHttpAuthHandlerBase> aw_http_auth_handler_;
+  scoped_refptr<net::AuthChallengeInfo> auth_info_;
+  net::URLRequest* request_;
+  int render_process_id_;
+  int render_frame_id_;
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_LOGIN_DELEGATE_H_
diff --git a/android_webview/browser/aw_media_client_android.cc b/android_webview/browser/aw_media_client_android.cc
new file mode 100644
index 0000000..9bb7d74
--- /dev/null
+++ b/android_webview/browser/aw_media_client_android.cc
@@ -0,0 +1,73 @@
+// Copyright 2015 The Chromium Authors. 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/aw_media_client_android.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+
+namespace android_webview {
+
+namespace {
+
+const size_t kGUIDLength = 36U;
+
+#define RCHECK(x)                                    \
+  if (!(x)) {                                        \
+    LOG(ERROR) << "Can't parse key-system mapping: " \
+               << key_system_uuid_mapping;           \
+    return std::make_pair("", uuid);                 \
+  }
+
+media::MediaClientAndroid::KeySystemUuidMap::value_type CreateMappingFromString(
+    const std::string& key_system_uuid_mapping) {
+  std::vector<uint8_t> uuid;
+
+  std::vector<std::string> tokens =
+      base::SplitString(key_system_uuid_mapping, ",", base::KEEP_WHITESPACE,
+                        base::SPLIT_WANT_NONEMPTY);
+  RCHECK(tokens.size() == 2);
+
+  std::string key_system;
+  base::TrimWhitespaceASCII(tokens[0], base::TRIM_ALL, &key_system);
+
+  std::string guid(tokens[1]);
+  RCHECK(guid.length() == kGUIDLength);
+  base::RemoveChars(guid, "-", &guid);
+  RCHECK(base::HexStringToBytes(guid, &uuid));
+
+  return std::make_pair(key_system, uuid);
+}
+
+}  // namespace
+
+AwMediaClientAndroid::AwMediaClientAndroid(
+    const std::vector<std::string>& key_system_uuid_mappings)
+    : key_system_uuid_mappings_(key_system_uuid_mappings) {
+}
+
+AwMediaClientAndroid::~AwMediaClientAndroid() {
+}
+
+void AwMediaClientAndroid::AddKeySystemUUIDMappings(KeySystemUuidMap* map) {
+  for (const std::string& key_system_uuid_mapping : key_system_uuid_mappings_) {
+    auto mapping = CreateMappingFromString(key_system_uuid_mapping);
+    if (!mapping.first.empty())
+      map->insert(mapping);
+  }
+}
+
+media::MediaDrmBridgeDelegate* AwMediaClientAndroid::GetMediaDrmBridgeDelegate(
+    const media::UUID& scheme_uuid) {
+  if (scheme_uuid == widevine_delegate_.GetUUID())
+    return &widevine_delegate_;
+  return nullptr;
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_media_client_android.h b/android_webview/browser/aw_media_client_android.h
new file mode 100644
index 0000000..a2a6718
--- /dev/null
+++ b/android_webview/browser/aw_media_client_android.h
@@ -0,0 +1,36 @@
+// Copyright 2015 The Chromium Authors. 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_AW_MEDIA_CLIENT_ANDROID_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_MEDIA_CLIENT_ANDROID_H_
+
+#include "base/macros.h"
+#include "components/cdm/browser/widevine_drm_delegate_android.h"
+#include "media/base/android/media_client_android.h"
+
+namespace android_webview {
+
+class AwMediaClientAndroid : public media::MediaClientAndroid {
+ public:
+  // |key_system_uuid_mappings| is a list of strings containing key-system/UUID
+  // pairs, in the format "key system name,UUID as string".
+  explicit AwMediaClientAndroid(
+      const std::vector<std::string>& key_system_uuid_mappings);
+  ~AwMediaClientAndroid() override;
+
+ private:
+  // media::MediaClientAndroid implementation:
+  void AddKeySystemUUIDMappings(KeySystemUuidMap* map) override;
+  media::MediaDrmBridgeDelegate* GetMediaDrmBridgeDelegate(
+      const media::UUID& scheme_uuid) override;
+
+  std::vector<std::string> key_system_uuid_mappings_;
+  cdm::WidevineDrmDelegateAndroid widevine_delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwMediaClientAndroid);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_MEDIA_CLIENT_ANDROID_H_
diff --git a/android_webview/browser/aw_message_port_message_filter.cc b/android_webview/browser/aw_message_port_message_filter.cc
new file mode 100644
index 0000000..0232b33
--- /dev/null
+++ b/android_webview/browser/aw_message_port_message_filter.cc
@@ -0,0 +1,108 @@
+// Copyright 2015 The Chromium Authors. 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/aw_message_port_message_filter.h"
+
+#include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/common/aw_message_port_messages.h"
+#include "content/public/browser/message_port_provider.h"
+#include "content/public/common/message_port_types.h"
+
+using content::BrowserThread;
+using content::MessagePortProvider;
+
+namespace android_webview {
+
+AwMessagePortMessageFilter::AwMessagePortMessageFilter(int route_id)
+    : BrowserMessageFilter(AwMessagePortMsgStart), route_id_(route_id) {
+}
+
+AwMessagePortMessageFilter::~AwMessagePortMessageFilter() {
+}
+
+void AwMessagePortMessageFilter::OnChannelClosing() {
+  MessagePortProvider::OnMessagePortDelegateClosing(this);
+  AwBrowserContext::GetDefault()->GetMessagePortService()->
+      OnMessagePortMessageFilterClosing(this);
+}
+
+bool AwMessagePortMessageFilter::OnMessageReceived(
+    const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(AwMessagePortMessageFilter, message)
+    IPC_MESSAGE_FORWARD(AwMessagePortHostMsg_ConvertedWebToAppMessage,
+                        AwBrowserContext::GetDefault()->GetMessagePortService(),
+                        AwMessagePortService::OnConvertedWebToAppMessage)
+    IPC_MESSAGE_HANDLER(AwMessagePortHostMsg_ConvertedAppToWebMessage,
+                        OnConvertedAppToWebMessage)
+    IPC_MESSAGE_HANDLER(AwMessagePortHostMsg_ClosePortAck, OnClosePortAck)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void AwMessagePortMessageFilter::OnConvertedAppToWebMessage(
+    int msg_port_id,
+    const base::string16& message,
+    const std::vector<int>& sent_message_port_ids) {
+  std::vector<content::TransferredMessagePort>
+      sent_ports(sent_message_port_ids.size());
+  for (size_t i = 0; i < sent_message_port_ids.size(); ++i)
+    sent_ports[i].id = sent_message_port_ids[i];
+  // TODO(mek): Bypass the extra roundtrip and just send the unconverted message
+  // to the renderer directly.
+  MessagePortProvider::PostMessageToPort(msg_port_id,
+      content::MessagePortMessage(message),
+      sent_ports);
+}
+
+void AwMessagePortMessageFilter::OnClosePortAck(int message_port_id) {
+  MessagePortProvider::ClosePort(message_port_id);
+  AwBrowserContext::GetDefault()->GetMessagePortService()->
+      CleanupPort(message_port_id);
+}
+
+void AwMessagePortMessageFilter::OnDestruct() const {
+  BrowserThread::DeleteOnIOThread::Destruct(this);
+}
+
+void AwMessagePortMessageFilter::SendAppToWebMessage(
+    int msg_port_route_id,
+    const base::string16& message,
+    const std::vector<int>& sent_message_port_ids) {
+  Send(new AwMessagePortMsg_AppToWebMessage(
+      route_id_,
+      msg_port_route_id, // same as the port id
+      message, sent_message_port_ids));
+}
+
+void AwMessagePortMessageFilter::SendClosePortMessage(int message_port_id) {
+  Send(new AwMessagePortMsg_ClosePort(route_id_, message_port_id));
+}
+
+void AwMessagePortMessageFilter::SendMessage(
+    int msg_port_route_id,
+    const content::MessagePortMessage& message,
+    const std::vector<content::TransferredMessagePort>& sent_message_ports) {
+  DCHECK(message.is_string());
+  std::vector<int> sent_message_port_ids(sent_message_ports.size());
+  for (size_t i = 0; i < sent_message_ports.size(); ++i) {
+    DCHECK(!sent_message_ports[i].send_messages_as_values);
+    int sent_port_id = sent_message_ports[i].id;
+    MessagePortProvider::HoldMessages(sent_port_id);
+    MessagePortProvider::UpdateMessagePort(sent_port_id, this);
+    sent_message_port_ids[i] = sent_port_id;
+  }
+  Send(new AwMessagePortMsg_WebToAppMessage(
+      route_id_,
+      msg_port_route_id, // same as the port id
+      message.message_as_string, sent_message_port_ids));
+}
+
+void AwMessagePortMessageFilter::SendMessagesAreQueued(int route_id) {
+  // TODO(sgurun) implement
+  NOTREACHED();
+}
+
+}   // namespace android_webview
diff --git a/android_webview/browser/aw_message_port_message_filter.h b/android_webview/browser/aw_message_port_message_filter.h
new file mode 100644
index 0000000..4dfeed6
--- /dev/null
+++ b/android_webview/browser/aw_message_port_message_filter.h
@@ -0,0 +1,57 @@
+// Copyright 2015 The Chromium Authors. 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_MESSAGE_PORT_MESSAGE_FILTER_H_
+#define ANDROID_WEBVIEW_BROWSER_MESSAGE_PORT_MESSAGE_FILTER_H_
+
+#include "base/callback.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/message_port_delegate.h"
+
+namespace android_webview {
+
+// Filter for Aw specific MessagePort related IPC messages (creating and
+// destroying a MessagePort, sending a message via a MessagePort etc).
+class AwMessagePortMessageFilter : public content::BrowserMessageFilter,
+                                   public content::MessagePortDelegate {
+ public:
+  explicit AwMessagePortMessageFilter(int route_id);
+
+  // BrowserMessageFilter implementation.
+  void OnChannelClosing() override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+  void OnDestruct() const override;
+
+  void SendAppToWebMessage(int msg_port_route_id,
+                           const base::string16& message,
+                           const std::vector<int>& sent_message_port_ids);
+  void SendClosePortMessage(int message_port_id);
+
+  // MessagePortDelegate implementation.
+  void SendMessage(
+      int msg_port_route_id,
+      const content::MessagePortMessage& message,
+      const std::vector<content::TransferredMessagePort>& sent_message_ports)
+      override;
+  void SendMessagesAreQueued(int route_id) override;
+ private:
+  friend class content::BrowserThread;
+  friend class base::DeleteHelper<AwMessagePortMessageFilter>;
+
+  void OnConvertedAppToWebMessage(
+      int msg_port_id,
+      const base::string16& message,
+      const std::vector<int>& sent_message_port_ids);
+  void OnClosePortAck(int message_port_id);
+
+  ~AwMessagePortMessageFilter() override;
+
+  int route_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwMessagePortMessageFilter);
+};
+
+}   // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_MESSAGE_PORT_MESSAGE_FILTER_H_
diff --git a/android_webview/browser/aw_message_port_service.h b/android_webview/browser/aw_message_port_service.h
new file mode 100644
index 0000000..779d90c
--- /dev/null
+++ b/android_webview/browser/aw_message_port_service.h
@@ -0,0 +1,34 @@
+// Copyright 2015 The Chromium Authors. 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_AW_MESSAGE_PORT_SERVICE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_MESSAGE_PORT_SERVICE_H_
+
+#include <vector>
+
+#include "base/values.h"
+
+namespace android_webview {
+
+class AwMessagePortMessageFilter;
+
+// The interface for AwMessagePortService
+class AwMessagePortService  {
+ public:
+  virtual ~AwMessagePortService() { }
+
+  virtual void OnConvertedWebToAppMessage(
+      int message_port_id,
+      const base::ListValue& message,
+      const std::vector<int>& sent_message_port_ids) = 0;
+
+  virtual void OnMessagePortMessageFilterClosing(
+      AwMessagePortMessageFilter* filter) = 0;
+
+  virtual void CleanupPort(int message_port_id) = 0;
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_MESSAGE_PORT_SERVICE_H_
diff --git a/android_webview/browser/aw_permission_manager.cc b/android_webview/browser/aw_permission_manager.cc
new file mode 100644
index 0000000..6fe1e1e
--- /dev/null
+++ b/android_webview/browser/aw_permission_manager.cc
@@ -0,0 +1,317 @@
+// Copyright 2015 The Chromium Authors. 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/aw_permission_manager.h"
+
+#include <string>
+
+#include "android_webview/browser/aw_browser_permission_request_delegate.h"
+#include "base/callback.h"
+#include "base/containers/hash_tables.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "content/public/browser/permission_type.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/web_contents.h"
+
+using content::PermissionStatus;
+using content::PermissionType;
+
+namespace android_webview {
+
+class LastRequestResultCache {
+ public:
+  LastRequestResultCache() : weak_factory_(this) {}
+
+  void SetResult(PermissionType permission,
+                 const GURL& requesting_origin,
+                 const GURL& embedding_origin,
+                 PermissionStatus status) {
+    DCHECK(status == content::PERMISSION_STATUS_GRANTED ||
+           status == content::PERMISSION_STATUS_DENIED);
+
+    // TODO(ddorwin): We should be denying empty origins at a higher level.
+    if (requesting_origin.is_empty() || embedding_origin.is_empty()) {
+      DLOG(WARNING) << "Not caching result because of empty origin.";
+      return;
+    }
+
+    if (!requesting_origin.is_valid()) {
+      NOTREACHED() << requesting_origin.possibly_invalid_spec();
+      return;
+    }
+    if (!embedding_origin.is_valid()) {
+      NOTREACHED() << embedding_origin.possibly_invalid_spec();
+      return;
+    }
+
+    if (permission != PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
+      // Other permissions are not cached.
+      return;
+    }
+
+    std::string key = GetCacheKey(requesting_origin, embedding_origin);
+    if (key.empty()) {
+      NOTREACHED();
+      // Never store an empty key because it could inadvertently be used for
+      // another combination.
+      return;
+    }
+    pmi_result_cache_[key] = status;
+  }
+
+  PermissionStatus GetResult(PermissionType permission,
+                             const GURL& requesting_origin,
+                             const GURL& embedding_origin) const {
+    // TODO(ddorwin): We should be denying empty origins at a higher level.
+    if (requesting_origin.is_empty() || embedding_origin.is_empty()) {
+      return content::PERMISSION_STATUS_ASK;
+    }
+
+    DCHECK(requesting_origin.is_valid())
+        << requesting_origin.possibly_invalid_spec();
+    DCHECK(embedding_origin.is_valid())
+        << embedding_origin.possibly_invalid_spec();
+
+    if (permission != PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
+      NOTREACHED() << "Results are only cached for PROTECTED_MEDIA_IDENTIFIER";
+      return content::PERMISSION_STATUS_ASK;
+    }
+
+    std::string key = GetCacheKey(requesting_origin, embedding_origin);
+    StatusMap::const_iterator it = pmi_result_cache_.find(key);
+    if (it == pmi_result_cache_.end()) {
+      DLOG(WARNING) << "GetResult() called for uncached origins: " << key;
+      return content::PERMISSION_STATUS_ASK;
+    }
+
+    DCHECK(!key.empty());
+    return it->second;
+  }
+
+  void ClearResult(PermissionType permission,
+                   const GURL& requesting_origin,
+                   const GURL& embedding_origin) {
+    // TODO(ddorwin): We should be denying empty origins at a higher level.
+    if (requesting_origin.is_empty() || embedding_origin.is_empty()) {
+      return;
+    }
+
+    DCHECK(requesting_origin.is_valid())
+        << requesting_origin.possibly_invalid_spec();
+    DCHECK(embedding_origin.is_valid())
+        << embedding_origin.possibly_invalid_spec();
+
+
+    if (permission != PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
+      // Other permissions are not cached, so nothing to clear.
+      return;
+    }
+
+    std::string key = GetCacheKey(requesting_origin, embedding_origin);
+    pmi_result_cache_.erase(key);
+  }
+
+  base::WeakPtr<LastRequestResultCache> GetWeakPtr() {
+    return weak_factory_.GetWeakPtr();
+  }
+
+ private:
+  // Returns a concatenation of the origins to be used as the index.
+  // Returns the empty string if either origin is invalid or empty.
+  static std::string GetCacheKey(const GURL& requesting_origin,
+                                 const GURL& embedding_origin) {
+    const std::string& requesting = requesting_origin.spec();
+    const std::string& embedding = embedding_origin.spec();
+    if (requesting.empty() || embedding.empty())
+      return std::string();
+    return requesting + "," + embedding;
+  }
+
+  using StatusMap = base::hash_map<std::string, PermissionStatus>;
+  StatusMap pmi_result_cache_;
+
+  base::WeakPtrFactory<LastRequestResultCache> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(LastRequestResultCache);
+};
+
+namespace {
+
+void CallbackPermisisonStatusWrapper(
+    const base::WeakPtr<LastRequestResultCache>& result_cache,
+    const base::Callback<void(PermissionStatus)>& callback,
+    PermissionType permission,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin,
+    bool allowed) {
+  PermissionStatus status = allowed ? content::PERMISSION_STATUS_GRANTED
+                                    : content::PERMISSION_STATUS_DENIED;
+  if (result_cache.get()) {
+    result_cache->SetResult(permission, requesting_origin, embedding_origin,
+                            status);
+  }
+
+  callback.Run(status);
+}
+
+}  // anonymous namespace
+
+AwPermissionManager::AwPermissionManager()
+    : content::PermissionManager(), result_cache_(new LastRequestResultCache) {
+}
+
+AwPermissionManager::~AwPermissionManager() {
+}
+
+void AwPermissionManager::RequestPermission(
+    PermissionType permission,
+    content::RenderFrameHost* render_frame_host,
+    int request_id,
+    const GURL& origin,
+    bool user_gesture,
+    const base::Callback<void(PermissionStatus)>& callback) {
+  int render_process_id = render_frame_host->GetProcess()->GetID();
+  int render_frame_id = render_frame_host->GetRoutingID();
+  AwBrowserPermissionRequestDelegate* delegate =
+      AwBrowserPermissionRequestDelegate::FromID(render_process_id,
+                                                 render_frame_id);
+  if (!delegate) {
+    DVLOG(0) << "Dropping permission request for "
+             << static_cast<int>(permission);
+    callback.Run(content::PERMISSION_STATUS_DENIED);
+    return;
+  }
+
+  const GURL& embedding_origin =
+      content::WebContents::FromRenderFrameHost(render_frame_host)
+          ->GetLastCommittedURL().GetOrigin();
+
+  switch (permission) {
+    case PermissionType::GEOLOCATION:
+      delegate->RequestGeolocationPermission(
+          origin, base::Bind(&CallbackPermisisonStatusWrapper,
+                             result_cache_->GetWeakPtr(), callback, permission,
+                             origin, embedding_origin));
+      break;
+    case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
+      delegate->RequestProtectedMediaIdentifierPermission(
+          origin, base::Bind(&CallbackPermisisonStatusWrapper,
+                             result_cache_->GetWeakPtr(), callback, permission,
+                             origin, embedding_origin));
+      break;
+    case PermissionType::MIDI_SYSEX:
+      delegate->RequestMIDISysexPermission(
+          origin, base::Bind(&CallbackPermisisonStatusWrapper,
+                             result_cache_->GetWeakPtr(), callback, permission,
+                             origin, embedding_origin));
+      break;
+    case PermissionType::AUDIO_CAPTURE:
+    case PermissionType::VIDEO_CAPTURE:
+    case PermissionType::NOTIFICATIONS:
+    case PermissionType::PUSH_MESSAGING:
+    case PermissionType::DURABLE_STORAGE:
+      NOTIMPLEMENTED() << "RequestPermission is not implemented for "
+                       << static_cast<int>(permission);
+      callback.Run(content::PERMISSION_STATUS_DENIED);
+      break;
+    case PermissionType::MIDI:
+      callback.Run(content::PERMISSION_STATUS_GRANTED);
+      break;
+    case PermissionType::NUM:
+      NOTREACHED() << "PermissionType::NUM was not expected here.";
+      callback.Run(content::PERMISSION_STATUS_DENIED);
+      break;
+  }
+}
+
+void AwPermissionManager::CancelPermissionRequest(
+    PermissionType permission,
+    content::RenderFrameHost* render_frame_host,
+    int request_id,
+    const GURL& origin) {
+  // The caller is canceling (presumably) the most recent request. Assuming the
+  // request did not complete, the user did not respond to the requset.
+  // Thus, assume we do not know the result.
+  const GURL& embedding_origin =
+      content::WebContents::FromRenderFrameHost(render_frame_host)
+          ->GetLastCommittedURL().GetOrigin();
+  result_cache_->ClearResult(permission, origin, embedding_origin);
+
+  int render_process_id = render_frame_host->GetProcess()->GetID();
+  int render_frame_id = render_frame_host->GetRoutingID();
+  AwBrowserPermissionRequestDelegate* delegate =
+      AwBrowserPermissionRequestDelegate::FromID(render_process_id,
+                                                 render_frame_id);
+  if (!delegate)
+    return;
+
+  switch (permission) {
+    case PermissionType::GEOLOCATION:
+      delegate->CancelGeolocationPermissionRequests(origin);
+      break;
+    case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
+      delegate->CancelProtectedMediaIdentifierPermissionRequests(origin);
+      break;
+    case PermissionType::MIDI_SYSEX:
+      delegate->CancelMIDISysexPermissionRequests(origin);
+      break;
+    case PermissionType::NOTIFICATIONS:
+    case PermissionType::PUSH_MESSAGING:
+    case PermissionType::DURABLE_STORAGE:
+    case PermissionType::AUDIO_CAPTURE:
+    case PermissionType::VIDEO_CAPTURE:
+      NOTIMPLEMENTED() << "CancelPermission not implemented for "
+                       << static_cast<int>(permission);
+      break;
+    case PermissionType::MIDI:
+      // There is nothing to cancel so this is simply ignored.
+      break;
+    case PermissionType::NUM:
+      NOTREACHED() << "PermissionType::NUM was not expected here.";
+      break;
+  }
+}
+
+void AwPermissionManager::ResetPermission(PermissionType permission,
+                                          const GURL& requesting_origin,
+                                          const GURL& embedding_origin) {
+  result_cache_->ClearResult(permission, requesting_origin, embedding_origin);
+}
+
+PermissionStatus AwPermissionManager::GetPermissionStatus(
+    PermissionType permission,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin) {
+  // Method is called outside the Permissions API only for this permission.
+  if (permission == PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
+    return result_cache_->GetResult(permission, requesting_origin,
+                                    embedding_origin);
+  } else if (permission == PermissionType::MIDI) {
+    return content::PERMISSION_STATUS_GRANTED;
+  }
+
+  return content::PERMISSION_STATUS_DENIED;
+}
+
+void AwPermissionManager::RegisterPermissionUsage(
+    PermissionType permission,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin) {
+}
+
+int AwPermissionManager::SubscribePermissionStatusChange(
+    PermissionType permission,
+    const GURL& requesting_origin,
+    const GURL& embedding_origin,
+    const base::Callback<void(PermissionStatus)>& callback) {
+  return -1;
+}
+
+void AwPermissionManager::UnsubscribePermissionStatusChange(
+    int subscription_id) {
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_permission_manager.h b/android_webview/browser/aw_permission_manager.h
new file mode 100644
index 0000000..842170b
--- /dev/null
+++ b/android_webview/browser/aw_permission_manager.h
@@ -0,0 +1,59 @@
+// Copyright 2015 The Chromium Authors. 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_AW_PERMISSION_MANAGER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_PERMISSION_MANAGER_H_
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/permission_manager.h"
+
+namespace android_webview {
+
+class LastRequestResultCache;
+
+class AwPermissionManager : public content::PermissionManager {
+ public:
+  AwPermissionManager();
+  ~AwPermissionManager() override;
+
+  // PermissionManager implementation.
+  void RequestPermission(
+      content::PermissionType permission,
+      content::RenderFrameHost* render_frame_host,
+      int request_id,
+      const GURL& requesting_origin,
+      bool user_gesture,
+      const base::Callback<void(content::PermissionStatus)>& callback) override;
+  void CancelPermissionRequest(content::PermissionType permission,
+                               content::RenderFrameHost* render_frame_host,
+                               int request_id,
+                               const GURL& requesting_origin) override;
+  void ResetPermission(content::PermissionType permission,
+                       const GURL& requesting_origin,
+                       const GURL& embedding_origin) override;
+  content::PermissionStatus GetPermissionStatus(
+      content::PermissionType permission,
+      const GURL& requesting_origin,
+      const GURL& embedding_origin) override;
+  void RegisterPermissionUsage(content::PermissionType permission,
+                               const GURL& requesting_origin,
+                               const GURL& embedding_origin) override;
+  int SubscribePermissionStatusChange(
+      content::PermissionType permission,
+      const GURL& requesting_origin,
+      const GURL& embedding_origin,
+      const base::Callback<void(content::PermissionStatus)>& callback) override;
+  void UnsubscribePermissionStatusChange(int subscription_id) override;
+
+ private:
+  scoped_ptr<LastRequestResultCache> result_cache_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwPermissionManager);
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_BROWSER_AW_PERMISSION_MANAGER_H_
diff --git a/android_webview/browser/aw_pref_store.cc b/android_webview/browser/aw_pref_store.cc
new file mode 100644
index 0000000..4c8f9176
--- /dev/null
+++ b/android_webview/browser/aw_pref_store.cc
@@ -0,0 +1,76 @@
+// 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 "android_webview/browser/aw_pref_store.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+
+AwPrefStore::AwPrefStore() {}
+
+AwPrefStore::~AwPrefStore() {}
+
+bool AwPrefStore::GetValue(const std::string& key,
+                           const base::Value** value) const {
+  return prefs_.GetValue(key, value);
+}
+
+bool AwPrefStore::GetMutableValue(const std::string& key,
+                                  base::Value** value) {
+  return prefs_.GetValue(key, value);
+}
+
+void AwPrefStore::AddObserver(PrefStore::Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void AwPrefStore::RemoveObserver(PrefStore::Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+bool AwPrefStore::HasObservers() const {
+  return observers_.might_have_observers();
+}
+
+bool AwPrefStore::IsInitializationComplete() const {
+  return true;
+}
+
+void AwPrefStore::SetValue(const std::string& key,
+                           scoped_ptr<base::Value> value,
+                           uint32 flags) {
+  DCHECK(value);
+  if (prefs_.SetValue(key, value.Pass()))
+    ReportValueChanged(key, flags);
+}
+
+void AwPrefStore::SetValueSilently(const std::string& key,
+                                   scoped_ptr<base::Value> value,
+                                   uint32 flags) {
+  prefs_.SetValue(key, value.Pass());
+}
+
+void AwPrefStore::RemoveValue(const std::string& key, uint32 flags) {
+  if (prefs_.RemoveValue(key))
+    ReportValueChanged(key, flags);
+}
+
+bool AwPrefStore::ReadOnly() const {
+  return false;
+}
+
+PersistentPrefStore::PrefReadError AwPrefStore::GetReadError() const {
+  return PersistentPrefStore::PREF_READ_ERROR_NONE;
+}
+
+PersistentPrefStore::PrefReadError AwPrefStore::ReadPrefs() {
+  return PersistentPrefStore::PREF_READ_ERROR_NONE;
+}
+
+void AwPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate_raw) {
+}
+
+void AwPrefStore::ReportValueChanged(const std::string& key, uint32 flags) {
+  FOR_EACH_OBSERVER(Observer, observers_, OnPrefValueChanged(key));
+}
diff --git a/android_webview/browser/aw_pref_store.h b/android_webview/browser/aw_pref_store.h
new file mode 100644
index 0000000..fd85639f
--- /dev/null
+++ b/android_webview/browser/aw_pref_store.h
@@ -0,0 +1,61 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_PREF_STORE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_PREF_STORE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/observer_list.h"
+#include "base/prefs/persistent_pref_store.h"
+#include "base/prefs/pref_value_map.h"
+
+// A light-weight prefstore implementation that keeps preferences
+// in a memory backed store. This is not a persistent prefstore -- we
+// subclass the PersistentPrefStore here since it is needed by the
+// PrefService, which in turn is needed by the Autofill component.
+class AwPrefStore : public PersistentPrefStore {
+ public:
+  AwPrefStore();
+
+  // Overriden from PrefStore.
+  bool GetValue(const std::string& key,
+                const base::Value** result) const override;
+  void AddObserver(PrefStore::Observer* observer) override;
+  void RemoveObserver(PrefStore::Observer* observer) override;
+  bool HasObservers() const override;
+  bool IsInitializationComplete() const override;
+
+  // PersistentPrefStore overrides:
+  bool GetMutableValue(const std::string& key, base::Value** result) override;
+  void ReportValueChanged(const std::string& key, uint32 flags) override;
+  void SetValue(const std::string& key,
+                scoped_ptr<base::Value> value,
+                uint32 flags) override;
+  void SetValueSilently(const std::string& key,
+                        scoped_ptr<base::Value> value,
+                        uint32 flags) override;
+  void RemoveValue(const std::string& key, uint32 flags) override;
+  bool ReadOnly() const override;
+  PrefReadError GetReadError() const override;
+  PersistentPrefStore::PrefReadError ReadPrefs() override;
+  void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override;
+  void CommitPendingWrite() override {}
+  void SchedulePendingLossyWrites() override {}
+
+ protected:
+  ~AwPrefStore() override;
+
+ private:
+  // Stores the preference values.
+  PrefValueMap prefs_;
+
+  base::ObserverList<PrefStore::Observer, true> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwPrefStore);
+};
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_PREF_STORE_H_
diff --git a/android_webview/browser/aw_print_manager.cc b/android_webview/browser/aw_print_manager.cc
new file mode 100644
index 0000000..8074809
--- /dev/null
+++ b/android_webview/browser/aw_print_manager.cc
@@ -0,0 +1,67 @@
+// Copyright 2015 The Chromium Authors. 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/aw_print_manager.h"
+
+#include "components/printing/browser/print_manager_utils.h"
+#include "components/printing/common/print_messages.h"
+#include "content/public/browser/browser_thread.h"
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(android_webview::AwPrintManager);
+
+namespace android_webview {
+
+// static
+AwPrintManager* AwPrintManager::CreateForWebContents(
+    content::WebContents* contents,
+    const printing::PrintSettings& settings,
+    const base::FileDescriptor& file_descriptor,
+    const PrintManager::PdfWritingDoneCallback& callback) {
+  AwPrintManager* print_manager =
+      new AwPrintManager(contents, settings, file_descriptor, callback);
+  contents->SetUserData(UserDataKey(), print_manager);
+  return print_manager;
+}
+
+AwPrintManager::AwPrintManager(
+    content::WebContents* contents,
+    const printing::PrintSettings& settings,
+    const base::FileDescriptor& file_descriptor,
+    const PdfWritingDoneCallback& callback)
+    : PrintManager(contents),
+      settings_(settings) {
+  set_file_descriptor(file_descriptor);
+  pdf_writing_done_callback_ = callback;
+  cookie_ = 1;
+}
+
+AwPrintManager::~AwPrintManager() {
+}
+
+bool AwPrintManager::PrintNow() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  return Send(new PrintMsg_PrintPages(routing_id()));
+}
+
+bool AwPrintManager::OnMessageReceived(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(AwPrintManager, message)
+    IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_GetDefaultPrintSettings,
+                                    OnGetDefaultPrintSettings)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled ? true : PrintManager::OnMessageReceived(message);
+}
+
+void AwPrintManager::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
+  // Unlike the printing_message_filter, we do process this in UI thread.
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  PrintMsg_Print_Params params;
+  printing::RenderParamsFromPrintSettings(settings_, &params);
+  params.document_cookie = cookie_;
+  PrintHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, params);
+  Send(reply_msg);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_print_manager.h b/android_webview/browser/aw_print_manager.h
new file mode 100644
index 0000000..ae4648f
--- /dev/null
+++ b/android_webview/browser/aw_print_manager.h
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. 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_PRINT_MANAGER_H_
+#define ANDROID_WEBVIEW_BROWSER_PRINT_MANAGER_H_
+
+#include "components/printing/browser/print_manager.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "printing/print_settings.h"
+
+namespace android_webview {
+
+class AwPrintManager : public printing::PrintManager,
+    public content::WebContentsUserData<AwPrintManager> {
+ public:
+  // Creates a AwPrintManager for the provided webcontents. If the
+  // AwPrintManager already exists, it is destroyed and a new one is created.
+  static AwPrintManager* CreateForWebContents(
+      content::WebContents* contents,
+      const printing::PrintSettings& settings,
+      const base::FileDescriptor& file_descriptor,
+      const PdfWritingDoneCallback& callback);
+
+  ~AwPrintManager() override;
+
+  bool PrintNow();
+
+ private:
+  friend class content::WebContentsUserData<AwPrintManager>;
+  AwPrintManager(content::WebContents* contents,
+                 const printing::PrintSettings& settings,
+                 const base::FileDescriptor& file_descriptor,
+                 const PdfWritingDoneCallback& callback);
+
+  bool OnMessageReceived(const IPC::Message& message) override;
+  void OnGetDefaultPrintSettings(IPC::Message* reply_msg);
+
+  printing::PrintSettings settings_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwPrintManager);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_PRINT_MANAGER_H_
diff --git a/android_webview/browser/aw_printing_message_filter.cc b/android_webview/browser/aw_printing_message_filter.cc
new file mode 100644
index 0000000..144407b
--- /dev/null
+++ b/android_webview/browser/aw_printing_message_filter.cc
@@ -0,0 +1,87 @@
+// Copyright 2015 The Chromium Authors. 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/aw_printing_message_filter.h"
+
+#include "android_webview/browser/aw_print_manager.h"
+#include "components/printing/common/print_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents.h"
+
+using content::BrowserThread;
+using content::WebContents;
+
+namespace android_webview {
+
+namespace {
+
+AwPrintManager* GetPrintManager(int render_process_id, int render_view_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  content::RenderViewHost* view = content::RenderViewHost::FromID(
+      render_process_id, render_view_id);
+  if (!view)
+    return nullptr;
+  WebContents* web_contents = WebContents::FromRenderViewHost(view);
+  return web_contents ? AwPrintManager::FromWebContents(web_contents)
+                      : nullptr;
+}
+
+} // namespace
+
+AwPrintingMessageFilter::AwPrintingMessageFilter(int render_process_id)
+    : BrowserMessageFilter(PrintMsgStart),
+      render_process_id_(render_process_id) {
+}
+
+AwPrintingMessageFilter::~AwPrintingMessageFilter() {
+}
+
+void AwPrintingMessageFilter::OverrideThreadForMessage(
+    const IPC::Message& message, BrowserThread::ID* thread) {
+  if (message.type() == PrintHostMsg_AllocateTempFileForPrinting::ID ||
+      message.type() == PrintHostMsg_TempFileForPrintingWritten::ID) {
+    *thread = BrowserThread::UI;
+  }
+}
+
+bool AwPrintingMessageFilter::OnMessageReceived(const IPC::Message& message) {
+  // TODO(timvolodine): move this filter to component (crbug.com/500949).
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(AwPrintingMessageFilter, message)
+    IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting,
+                        OnAllocateTempFileForPrinting)
+    IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten,
+                        OnTempFileForPrintingWritten)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void AwPrintingMessageFilter::OnAllocateTempFileForPrinting(
+    int render_view_id,
+    base::FileDescriptor* temp_file_fd,
+    int* sequence_number) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  AwPrintManager* print_manager =
+      GetPrintManager(render_process_id_, render_view_id);
+  if (!print_manager)
+    return;
+
+  *sequence_number = 0;  // we don't really use the sequence number.
+  temp_file_fd->fd = print_manager->file_descriptor().fd;
+  temp_file_fd->auto_close = false;
+}
+
+void AwPrintingMessageFilter::OnTempFileForPrintingWritten(
+    int render_view_id,
+    int sequence_number) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  AwPrintManager* print_manager =
+      GetPrintManager(render_process_id_, render_view_id);
+  if (print_manager)
+    print_manager->PdfWritingDone(true);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_printing_message_filter.h b/android_webview/browser/aw_printing_message_filter.h
new file mode 100644
index 0000000..f5c159c
--- /dev/null
+++ b/android_webview/browser/aw_printing_message_filter.h
@@ -0,0 +1,40 @@
+// Copyright 2015 The Chromium Authors. 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_PRINTING_MESSAGE_FILTER_H_
+#define ANDROID_WEBVIEW_BROWSER_PRINTING_MESSAGE_FILTER_H_
+
+#include "content/public/browser/browser_message_filter.h"
+
+namespace android_webview {
+
+// This class filters out incoming printing related IPC messages for the
+// renderer process on the IPC thread.
+class AwPrintingMessageFilter : public content::BrowserMessageFilter {
+ public:
+  explicit AwPrintingMessageFilter(int render_process_id);
+
+  // content::BrowserMessageFilter methods.
+  void OverrideThreadForMessage(const IPC::Message& message,
+                                content::BrowserThread::ID* thread) override;
+  bool OnMessageReceived(const IPC::Message& message) override;
+
+ private:
+  ~AwPrintingMessageFilter() override;
+
+  // Used to ask the browser allocate a temporary file for the renderer
+  // to fill in resulting PDF in renderer.
+  void OnAllocateTempFileForPrinting(int render_view_id,
+                                     base::FileDescriptor* temp_file_fd,
+                                     int* sequence_number);
+  void OnTempFileForPrintingWritten(int render_view_id, int sequence_number);
+
+  const int render_process_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwPrintingMessageFilter);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_PRINTING_MESSAGE_FILTER_H_
diff --git a/android_webview/browser/aw_quota_manager_bridge.cc b/android_webview/browser/aw_quota_manager_bridge.cc
new file mode 100644
index 0000000..ad2f3e0
--- /dev/null
+++ b/android_webview/browser/aw_quota_manager_bridge.cc
@@ -0,0 +1,13 @@
+// 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 "android_webview/browser/aw_quota_manager_bridge.h"
+
+namespace android_webview {
+
+AwQuotaManagerBridge::AwQuotaManagerBridge() {}
+
+AwQuotaManagerBridge::~AwQuotaManagerBridge() {}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_quota_manager_bridge.h b/android_webview/browser/aw_quota_manager_bridge.h
new file mode 100644
index 0000000..bc4da378
--- /dev/null
+++ b/android_webview/browser/aw_quota_manager_bridge.h
@@ -0,0 +1,23 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_QUOTA_MANAGER_BRIDGE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_QUOTA_MANAGER_BRIDGE_H_
+
+#include "base/memory/ref_counted.h"
+
+namespace android_webview {
+
+// Empty base class so this can be refcounted by AwBrowserContext.
+class AwQuotaManagerBridge :
+    public base::RefCountedThreadSafe<AwQuotaManagerBridge> {
+ protected:
+  friend class base::RefCountedThreadSafe<AwQuotaManagerBridge>;
+  AwQuotaManagerBridge();
+  virtual ~AwQuotaManagerBridge();
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_QUOTA_MANAGER_BRIDGE_H_
diff --git a/android_webview/browser/aw_quota_permission_context.cc b/android_webview/browser/aw_quota_permission_context.cc
new file mode 100644
index 0000000..bb1c06c
--- /dev/null
+++ b/android_webview/browser/aw_quota_permission_context.cc
@@ -0,0 +1,29 @@
+// 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 "android_webview/browser/aw_quota_permission_context.h"
+
+#include "base/logging.h"
+
+using content::QuotaPermissionContext;
+
+namespace android_webview {
+
+AwQuotaPermissionContext::AwQuotaPermissionContext() {
+}
+
+AwQuotaPermissionContext::~AwQuotaPermissionContext() {
+}
+
+void AwQuotaPermissionContext::RequestQuotaPermission(
+    const content::StorageQuotaParams& params,
+    int render_process_id,
+    const PermissionCallback& callback) {
+  // Android WebView only uses storage::kStorageTypeTemporary type of storage
+  // with quota managed automatically, not through this interface. Therefore
+  // unconditionally disallow all quota requests here.
+  callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_quota_permission_context.h b/android_webview/browser/aw_quota_permission_context.h
new file mode 100644
index 0000000..035557e
--- /dev/null
+++ b/android_webview/browser/aw_quota_permission_context.h
@@ -0,0 +1,30 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_QUOTA_PERMISSION_CONTEXT_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_QUOTA_PERMISSION_CONTEXT_H_
+
+#include "base/compiler_specific.h"
+#include "content/public/browser/quota_permission_context.h"
+
+namespace android_webview {
+
+class AwQuotaPermissionContext : public content::QuotaPermissionContext {
+ public:
+  AwQuotaPermissionContext();
+
+  void RequestQuotaPermission(const content::StorageQuotaParams& params,
+                              int render_process_id,
+                              const PermissionCallback& callback) override;
+
+ private:
+  ~AwQuotaPermissionContext() override;
+
+  DISALLOW_COPY_AND_ASSIGN(AwQuotaPermissionContext);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_QUOTA_PERMISSION_CONTEXT_H_
+
diff --git a/android_webview/browser/aw_render_thread_context_provider.cc b/android_webview/browser/aw_render_thread_context_provider.cc
new file mode 100644
index 0000000..e928975
--- /dev/null
+++ b/android_webview/browser/aw_render_thread_context_provider.cc
@@ -0,0 +1,202 @@
+// Copyright 2015 The Chromium Authors. 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/aw_render_thread_context_provider.h"
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/lazy_instance.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/output/managed_memory_policy.h"
+#include "gpu/blink/webgraphicscontext3d_impl.h"
+#include "gpu/command_buffer/client/gl_in_process_context.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/gles2_lib.h"
+#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
+#include "third_party/skia/include/gpu/GrContext.h"
+#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
+
+namespace android_webview {
+
+namespace {
+
+// Singleton used to initialize and terminate the gles2 library.
+class GLES2Initializer {
+ public:
+  GLES2Initializer() { gles2::Initialize(); }
+
+  ~GLES2Initializer() { gles2::Terminate(); }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GLES2Initializer);
+};
+
+base::LazyInstance<GLES2Initializer> g_gles2_initializer =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+// static
+scoped_refptr<AwRenderThreadContextProvider>
+AwRenderThreadContextProvider::Create(
+    scoped_refptr<gfx::GLSurface> surface,
+    scoped_refptr<gpu::InProcessCommandBuffer::Service> service) {
+  return new AwRenderThreadContextProvider(surface, service);
+}
+
+AwRenderThreadContextProvider::AwRenderThreadContextProvider(
+    scoped_refptr<gfx::GLSurface> surface,
+    scoped_refptr<gpu::InProcessCommandBuffer::Service> service)
+    : destroyed_(false) {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  blink::WebGraphicsContext3D::Attributes attributes;
+  attributes.antialias = false;
+  attributes.depth = false;
+  attributes.stencil = false;
+  attributes.shareResources = true;
+  attributes.noAutomaticFlushes = true;
+  gpu::gles2::ContextCreationAttribHelper attribs_for_gles2;
+  gpu_blink::WebGraphicsContext3DImpl::ConvertAttributes(attributes,
+                                                         &attribs_for_gles2);
+  attribs_for_gles2.lose_context_when_out_of_memory = true;
+
+  context_.reset(gpu::GLInProcessContext::Create(
+      service,
+      surface,
+      surface->IsOffscreen(),
+      gfx::kNullAcceleratedWidget,
+      surface->GetSize(),
+      NULL /* share_context */,
+      false /* share_resources */,
+      attribs_for_gles2,
+      gfx::PreferDiscreteGpu,
+      gpu::GLInProcessContextSharedMemoryLimits(),
+      nullptr,
+      nullptr));
+
+  context_->SetContextLostCallback(base::Bind(
+      &AwRenderThreadContextProvider::OnLostContext, base::Unretained(this)));
+
+  capabilities_.gpu = context_->GetImplementation()->capabilities();
+}
+
+AwRenderThreadContextProvider::~AwRenderThreadContextProvider() {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+}
+
+bool AwRenderThreadContextProvider::BindToCurrentThread() {
+  // This is called on the thread the context will be used.
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  return true;
+}
+
+cc::ContextProvider::Capabilities
+AwRenderThreadContextProvider::ContextCapabilities() {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  return capabilities_;
+}
+
+gpu::gles2::GLES2Interface* AwRenderThreadContextProvider::ContextGL() {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  return context_->GetImplementation();
+}
+
+gpu::ContextSupport* AwRenderThreadContextProvider::ContextSupport() {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  return context_->GetImplementation();
+}
+
+static void BindGrContextCallback(const GrGLInterface* interface) {
+  cc::ContextProvider* context_provider =
+      reinterpret_cast<AwRenderThreadContextProvider*>(
+          interface->fCallbackData);
+
+  gles2::SetGLContext(context_provider->ContextGL());
+}
+
+class GrContext* AwRenderThreadContextProvider::GrContext() {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  if (gr_context_)
+    return gr_context_.get();
+
+  // The GrGLInterface factory will make GL calls using the C GLES2 interface.
+  // Make sure the gles2 library is initialized first on exactly one thread.
+  g_gles2_initializer.Get();
+  gles2::SetGLContext(ContextGL());
+
+  skia::RefPtr<GrGLInterface> interface =
+      skia::AdoptRef(skia_bindings::CreateCommandBufferSkiaGLBinding());
+  interface->fCallback = BindGrContextCallback;
+  interface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this);
+
+  gr_context_ = skia::AdoptRef(GrContext::Create(
+      kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get())));
+
+  return gr_context_.get();
+}
+
+void AwRenderThreadContextProvider::InvalidateGrContext(uint32_t state) {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  if (gr_context_)
+    gr_context_.get()->resetContext(state);
+}
+
+void AwRenderThreadContextProvider::SetupLock() {
+  context_->SetLock(&context_lock_);
+}
+
+base::Lock* AwRenderThreadContextProvider::GetLock() {
+  return &context_lock_;
+}
+
+void AwRenderThreadContextProvider::VerifyContexts() {
+}
+
+void AwRenderThreadContextProvider::DeleteCachedResources() {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  if (gr_context_) {
+    TRACE_EVENT_INSTANT0("gpu", "GrContext::freeGpuResources",
+                         TRACE_EVENT_SCOPE_THREAD);
+    gr_context_->freeGpuResources();
+  }
+}
+
+bool AwRenderThreadContextProvider::DestroyedOnMainThread() {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  return destroyed_;
+}
+
+void AwRenderThreadContextProvider::SetLostContextCallback(
+    const LostContextCallback& lost_context_callback) {
+  lost_context_callback_ = lost_context_callback;
+}
+
+void AwRenderThreadContextProvider::SetMemoryPolicyChangedCallback(
+    const MemoryPolicyChangedCallback& memory_policy_changed_callback) {
+  // There's no memory manager for the in-process implementation.
+}
+
+void AwRenderThreadContextProvider::OnLostContext() {
+  DCHECK(main_thread_checker_.CalledOnValidThread());
+
+  if (destroyed_)
+    return;
+  destroyed_ = true;
+
+  if (!lost_context_callback_.is_null())
+    base::ResetAndReturn(&lost_context_callback_).Run();
+  if (gr_context_)
+    gr_context_->abandonContext();
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_render_thread_context_provider.h b/android_webview/browser/aw_render_thread_context_provider.h
new file mode 100644
index 0000000..24c1463
--- /dev/null
+++ b/android_webview/browser/aw_render_thread_context_provider.h
@@ -0,0 +1,76 @@
+// Copyright 2015 The Chromium Authors. 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_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread_checker.h"
+#include "cc/output/context_provider.h"
+#include "gpu/command_buffer/service/in_process_command_buffer.h"
+#include "skia/ext/refptr.h"
+
+namespace gfx {
+class GLSurface;
+}
+
+namespace gpu {
+class GLInProcessContext;
+}
+
+namespace android_webview {
+
+class AwRenderThreadContextProvider : public cc::ContextProvider {
+ public:
+  static scoped_refptr<AwRenderThreadContextProvider> Create(
+      scoped_refptr<gfx::GLSurface> surface,
+      scoped_refptr<gpu::InProcessCommandBuffer::Service> service);
+
+ private:
+  AwRenderThreadContextProvider(
+      scoped_refptr<gfx::GLSurface> surface,
+      scoped_refptr<gpu::InProcessCommandBuffer::Service> service);
+  ~AwRenderThreadContextProvider() override;
+
+  // cc::ContextProvider:
+  bool BindToCurrentThread() override;
+  Capabilities ContextCapabilities() override;
+  gpu::gles2::GLES2Interface* ContextGL() override;
+  gpu::ContextSupport* ContextSupport() override;
+  class GrContext* GrContext() override;
+  void InvalidateGrContext(uint32_t state) override;
+  void SetupLock() override;
+  base::Lock* GetLock() override;
+  void VerifyContexts() override;
+  void DeleteCachedResources() override;
+  bool DestroyedOnMainThread() override;
+  void SetLostContextCallback(
+      const LostContextCallback& lost_context_callback) override;
+  void SetMemoryPolicyChangedCallback(
+      const MemoryPolicyChangedCallback& memory_policy_changed_callback)
+      override;
+
+  void OnLostContext();
+
+  base::ThreadChecker main_thread_checker_;
+
+  scoped_ptr<gpu::GLInProcessContext> context_;
+  skia::RefPtr<class GrContext> gr_context_;
+
+  cc::ContextProvider::Capabilities capabilities_;
+
+  LostContextCallback lost_context_callback_;
+
+  bool destroyed_;
+
+  base::Lock context_lock_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwRenderThreadContextProvider);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_RENDER_THREAD_CONTEXT_PROVIDER_H_
diff --git a/android_webview/browser/aw_request_interceptor.cc b/android_webview/browser/aw_request_interceptor.cc
new file mode 100644
index 0000000..f646e1f
--- /dev/null
+++ b/android_webview/browser/aw_request_interceptor.cc
@@ -0,0 +1,89 @@
+// 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 "android_webview/browser/aw_request_interceptor.h"
+
+#include "android_webview/browser/aw_contents_io_thread_client.h"
+#include "android_webview/browser/aw_web_resource_response.h"
+#include "base/android/jni_string.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/resource_request_info.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_job.h"
+
+using content::BrowserThread;
+using content::RenderViewHost;
+using content::ResourceRequestInfo;
+
+namespace android_webview {
+
+namespace {
+
+const void* kRequestAlreadyQueriedDataKey = &kRequestAlreadyQueriedDataKey;
+
+} // namespace
+
+AwRequestInterceptor::AwRequestInterceptor() {
+}
+
+AwRequestInterceptor::~AwRequestInterceptor() {
+}
+
+scoped_ptr<AwWebResourceResponse>
+AwRequestInterceptor::QueryForAwWebResourceResponse(
+    net::URLRequest* request) const {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  int render_process_id, render_frame_id;
+  if (!ResourceRequestInfo::GetRenderFrameForRequest(
+      request, &render_process_id, &render_frame_id))
+    return scoped_ptr<AwWebResourceResponse>();
+
+  scoped_ptr<AwContentsIoThreadClient> io_thread_client =
+      AwContentsIoThreadClient::FromID(render_process_id, render_frame_id);
+
+  if (!io_thread_client.get())
+    return scoped_ptr<AwWebResourceResponse>();
+
+  GURL referrer(request->referrer());
+  if (referrer.is_valid() &&
+      (!request->is_pending() || request->is_redirecting())) {
+    request->SetExtraRequestHeaderByName(net::HttpRequestHeaders::kReferer,
+                                         referrer.spec(), true);
+  }
+  return io_thread_client->ShouldInterceptRequest(request).Pass();
+}
+
+net::URLRequestJob* AwRequestInterceptor::MaybeInterceptRequest(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate) const {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  // See if we've already found out the aw_web_resource_response for this
+  // request.
+  // This is done not only for efficiency reasons, but also for correctness
+  // as it is possible for the Interceptor chain to be invoked more than once
+  // in which case we don't want to query the embedder multiple times.
+  // Note: The Interceptor chain is not invoked more than once if we create a
+  // URLRequestJob in this method, so this is only caching negative hits.
+  if (request->GetUserData(kRequestAlreadyQueriedDataKey))
+    return NULL;
+  request->SetUserData(kRequestAlreadyQueriedDataKey,
+                       new base::SupportsUserData::Data());
+
+  scoped_ptr<AwWebResourceResponse> aw_web_resource_response =
+      QueryForAwWebResourceResponse(request);
+
+  if (!aw_web_resource_response)
+    return NULL;
+
+  // The newly created job will own the AwWebResourceResponse.
+  return AwWebResourceResponse::CreateJobFor(
+      aw_web_resource_response.Pass(), request, network_delegate);
+}
+
+} // namespace android_webview
diff --git a/android_webview/browser/aw_request_interceptor.h b/android_webview/browser/aw_request_interceptor.h
new file mode 100644
index 0000000..a3c54b3
--- /dev/null
+++ b/android_webview/browser/aw_request_interceptor.h
@@ -0,0 +1,46 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_REQUEST_INTERCEPTOR_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_REQUEST_INTERCEPTOR_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "net/url_request/url_request_interceptor.h"
+
+class GURL;
+
+namespace net {
+class URLRequest;
+class URLRequestContextGetter;
+class URLRequestJob;
+class NetworkDelegate;
+}
+
+namespace android_webview {
+
+class AwWebResourceResponse;
+
+// This class allows the Java-side embedder to substitute the default
+// URLRequest of a given request for an alternative job that will read data
+// from a Java stream.
+class AwRequestInterceptor : public net::URLRequestInterceptor {
+ public:
+  AwRequestInterceptor();
+  ~AwRequestInterceptor() override;
+
+  // net::URLRequestInterceptor override --------------------------------------
+  net::URLRequestJob* MaybeInterceptRequest(
+      net::URLRequest* request,
+      net::NetworkDelegate* network_delegate) const override;
+
+ private:
+  scoped_ptr<AwWebResourceResponse> QueryForAwWebResourceResponse(
+      net::URLRequest* request) const;
+
+  DISALLOW_COPY_AND_ASSIGN(AwRequestInterceptor);
+};
+
+} // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_REQUEST_INTERCEPTOR_H_
diff --git a/android_webview/browser/aw_resource_context.cc b/android_webview/browser/aw_resource_context.cc
new file mode 100644
index 0000000..65682f54
--- /dev/null
+++ b/android_webview/browser/aw_resource_context.cc
@@ -0,0 +1,53 @@
+// 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 "android_webview/browser/aw_resource_context.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+
+using content::BrowserThread;
+
+namespace android_webview {
+
+AwResourceContext::AwResourceContext(net::URLRequestContextGetter* getter)
+    : getter_(getter) {
+  DCHECK(getter_);
+}
+
+AwResourceContext::~AwResourceContext() {
+}
+
+void AwResourceContext::SetExtraHeaders(
+    const GURL& url, const std::string& headers) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (!url.is_valid()) return;
+  base::AutoLock scoped_lock(extra_headers_lock_);
+  if (!headers.empty())
+    extra_headers_[url.spec()] = headers;
+  else
+    extra_headers_.erase(url.spec());
+}
+
+std::string AwResourceContext::GetExtraHeaders(const GURL& url) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (!url.is_valid()) return std::string();
+  base::AutoLock scoped_lock(extra_headers_lock_);
+  std::map<std::string, std::string>::iterator iter =
+      extra_headers_.find(url.spec());
+  return iter != extra_headers_.end() ? iter->second : std::string();
+}
+
+net::HostResolver* AwResourceContext::GetHostResolver() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  return getter_->GetURLRequestContext()->host_resolver();
+}
+
+net::URLRequestContext* AwResourceContext::GetRequestContext() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  return getter_->GetURLRequestContext();
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_resource_context.h b/android_webview/browser/aw_resource_context.h
new file mode 100644
index 0000000..49922ca
--- /dev/null
+++ b/android_webview/browser/aw_resource_context.h
@@ -0,0 +1,43 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_RESOURCE_CONTEXT_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_RESOURCE_CONTEXT_H_
+
+#include <map>
+#include <string>
+
+#include "base/synchronization/lock.h"
+#include "content/public/browser/resource_context.h"
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace android_webview {
+
+class AwResourceContext : public content::ResourceContext {
+ public:
+  explicit AwResourceContext(net::URLRequestContextGetter* getter);
+  ~AwResourceContext() override;
+
+  void SetExtraHeaders(const GURL& url, const std::string& headers);
+  std::string GetExtraHeaders(const GURL& url);
+
+  // content::ResourceContext implementation.
+  net::HostResolver* GetHostResolver() override;
+  net::URLRequestContext* GetRequestContext() override;
+
+ private:
+  net::URLRequestContextGetter* getter_;
+
+  base::Lock extra_headers_lock_;
+  std::map<std::string, std::string> extra_headers_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwResourceContext);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_RESOURCE_CONTEXT_H_
diff --git a/android_webview/browser/aw_result_codes.h b/android_webview/browser/aw_result_codes.h
new file mode 100644
index 0000000..5bbbe9a
--- /dev/null
+++ b/android_webview/browser/aw_result_codes.h
@@ -0,0 +1,21 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_RESULT_CODES_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_RESULT_CODES_H_
+
+#include "content/public/common/result_codes.h"
+
+namespace android_webview {
+
+enum ResultCode {
+  RESULT_CODE_START = content::RESULT_CODE_LAST_CODE,
+
+  // A critical resource file is missing.
+  RESULT_CODE_MISSING_DATA,
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_RESULT_CODES_H_
diff --git a/android_webview/browser/aw_ssl_host_state_delegate.cc b/android_webview/browser/aw_ssl_host_state_delegate.cc
new file mode 100644
index 0000000..1da4747
--- /dev/null
+++ b/android_webview/browser/aw_ssl_host_state_delegate.cc
@@ -0,0 +1,100 @@
+// 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 "android_webview/browser/aw_ssl_host_state_delegate.h"
+
+#include "net/base/hash_value.h"
+
+using content::SSLHostStateDelegate;
+
+namespace android_webview {
+
+namespace internal {
+net::SHA256HashValue getChainFingerprint256(const net::X509Certificate& cert) {
+  net::SHA256HashValue fingerprint =
+      net::X509Certificate::CalculateChainFingerprint256(
+          cert.os_cert_handle(), cert.GetIntermediateCertificates());
+  return fingerprint;
+}
+
+CertPolicy::CertPolicy() {
+}
+CertPolicy::~CertPolicy() {
+}
+
+// For an allowance, we consider a given |cert| to be a match to a saved
+// allowed cert if the |error| is an exact match to or subset of the errors
+// in the saved CertStatus.
+bool CertPolicy::Check(const net::X509Certificate& cert,
+                       net::CertStatus error) const {
+  net::SHA256HashValue fingerprint = getChainFingerprint256(cert);
+  std::map<net::SHA256HashValue, net::CertStatus,
+           net::SHA256HashValueLessThan>::const_iterator allowed_iter =
+      allowed_.find(fingerprint);
+  if ((allowed_iter != allowed_.end()) && (allowed_iter->second & error) &&
+      ((allowed_iter->second & error) == error)) {
+    return true;
+  }
+  return false;
+}
+
+void CertPolicy::Allow(const net::X509Certificate& cert,
+                       net::CertStatus error) {
+  // If this same cert had already been saved with a different error status,
+  // this will replace it with the new error status.
+  net::SHA256HashValue fingerprint = getChainFingerprint256(cert);
+  allowed_[fingerprint] = error;
+}
+
+}  // namespace internal
+
+AwSSLHostStateDelegate::AwSSLHostStateDelegate() {
+}
+
+AwSSLHostStateDelegate::~AwSSLHostStateDelegate() {
+}
+
+void AwSSLHostStateDelegate::HostRanInsecureContent(const std::string& host,
+                                                    int pid) {
+  // Intentional no-op for Android WebView.
+}
+
+bool AwSSLHostStateDelegate::DidHostRunInsecureContent(const std::string& host,
+                                                       int pid) const {
+  // Intentional no-op for Android WebView.
+  return false;
+}
+
+void AwSSLHostStateDelegate::AllowCert(const std::string& host,
+                                       const net::X509Certificate& cert,
+                                       net::CertStatus error) {
+  cert_policy_for_host_[host].Allow(cert, error);
+}
+
+void AwSSLHostStateDelegate::Clear() {
+  cert_policy_for_host_.clear();
+}
+
+SSLHostStateDelegate::CertJudgment AwSSLHostStateDelegate::QueryPolicy(
+    const std::string& host,
+    const net::X509Certificate& cert,
+    net::CertStatus error,
+    bool* expired_previous_decision) {
+  return cert_policy_for_host_[host].Check(cert, error)
+             ? SSLHostStateDelegate::ALLOWED
+             : SSLHostStateDelegate::DENIED;
+}
+
+void AwSSLHostStateDelegate::RevokeUserAllowExceptions(
+    const std::string& host) {
+  cert_policy_for_host_.erase(host);
+}
+
+bool AwSSLHostStateDelegate::HasAllowException(const std::string& host) const {
+  auto policy_iterator = cert_policy_for_host_.find(host);
+  return policy_iterator != cert_policy_for_host_.end() &&
+         policy_iterator->second.HasAllowException();
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_ssl_host_state_delegate.h b/android_webview/browser/aw_ssl_host_state_delegate.h
new file mode 100644
index 0000000..b5a34f4
--- /dev/null
+++ b/android_webview/browser/aw_ssl_host_state_delegate.h
@@ -0,0 +1,91 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_SSL_HOST_STATE_DELEGATE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_SSL_HOST_STATE_DELEGATE_H_
+
+#include <map>
+#include <string>
+
+#include "content/public/browser/ssl_host_state_delegate.h"
+#include "net/base/hash_value.h"
+#include "net/cert/cert_status_flags.h"
+#include "net/cert/x509_certificate.h"
+
+namespace android_webview {
+
+namespace internal {
+// This class maintains the policy for storing actions on certificate errors.
+class CertPolicy {
+ public:
+  CertPolicy();
+  ~CertPolicy();
+  // Returns true if the user has decided to proceed through the ssl error
+  // before. For a certificate to be allowed, it must not have any
+  // *additional* errors from when it was allowed.
+  bool Check(const net::X509Certificate& cert, net::CertStatus error) const;
+
+  // Causes the policy to allow this certificate for a given |error|. And
+  // remember the user's choice.
+  void Allow(const net::X509Certificate& cert, net::CertStatus error);
+
+  // Returns true if and only if there exists a user allow exception for some
+  // certificate.
+  bool HasAllowException() const { return allowed_.size() > 0; }
+
+ private:
+  // The set of fingerprints of allowed certificates.
+  std::map<net::SHA256HashValue, net::CertStatus, net::SHA256HashValueLessThan>
+      allowed_;
+};
+
+}  // namespace internal
+
+class AwSSLHostStateDelegate : public content::SSLHostStateDelegate {
+ public:
+  AwSSLHostStateDelegate();
+  ~AwSSLHostStateDelegate() override;
+
+  // Records that |cert| is permitted to be used for |host| in the future, for
+  // a specified |error| type.
+  void AllowCert(const std::string& host,
+                 const net::X509Certificate& cert,
+                 net::CertStatus error) override;
+
+  void Clear() override;
+
+  // Queries whether |cert| is allowed or denied for |host| and |error|.
+  content::SSLHostStateDelegate::CertJudgment QueryPolicy(
+      const std::string& host,
+      const net::X509Certificate& cert,
+      net::CertStatus error,
+      bool* expired_previous_decision) override;
+
+  // Records that a host has run insecure content.
+  void HostRanInsecureContent(const std::string& host, int pid) override;
+
+  // Returns whether the specified host ran insecure content.
+  bool DidHostRunInsecureContent(const std::string& host,
+                                 int pid) const override;
+
+  // Revokes all SSL certificate error allow exceptions made by the user for
+  // |host|.
+  void RevokeUserAllowExceptions(const std::string& host) override;
+
+  // Returns whether the user has allowed a certificate error exception for
+  // |host|. This does not mean that *all* certificate errors are allowed, just
+  // that there exists an exception. To see if a particular certificate and
+  // error combination exception is allowed, use QueryPolicy().
+  bool HasAllowException(const std::string& host) const override;
+
+ private:
+  // Certificate policies for each host.
+  std::map<std::string, internal::CertPolicy> cert_policy_for_host_;
+
+  DISALLOW_COPY_AND_ASSIGN(AwSSLHostStateDelegate);
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_SSL_HOST_STATE_DELEGATE_H_
diff --git a/android_webview/browser/aw_static_cookie_policy_unittest.cc b/android_webview/browser/aw_static_cookie_policy_unittest.cc
new file mode 100644
index 0000000..edeb315
--- /dev/null
+++ b/android_webview/browser/aw_static_cookie_policy_unittest.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 "android_webview/browser/aw_cookie_access_policy.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+class GURL;
+
+using android_webview::AwStaticCookiePolicy;
+using testing::Test;
+
+class AwStaticCookiePolicyTest : public Test {
+ public:
+  static const GURL kUrlFirstParty;
+  static const GURL kUrlThirdParty;
+
+  AwStaticCookiePolicyTest() {}
+
+  void expectFirstPartyAccess(const AwStaticCookiePolicy& policy,
+                              bool expectedResult) {
+    EXPECT_EQ(expectedResult, policy.AllowSet(kUrlFirstParty, kUrlFirstParty));
+    EXPECT_EQ(expectedResult, policy.AllowGet(kUrlFirstParty, kUrlFirstParty));
+  }
+
+  void expectThirdPartyAccess(const AwStaticCookiePolicy& policy,
+                              bool expectedResult) {
+    EXPECT_EQ(expectedResult, policy.AllowSet(kUrlFirstParty, kUrlThirdParty));
+    EXPECT_EQ(expectedResult, policy.AllowGet(kUrlFirstParty, kUrlThirdParty));
+  }
+};
+
+const GURL AwStaticCookiePolicyTest::kUrlFirstParty =
+    GURL("http://first.example");
+const GURL AwStaticCookiePolicyTest::kUrlThirdParty =
+    GURL("http://third.example");
+
+TEST_F(AwStaticCookiePolicyTest, BlockAllCookies) {
+  AwStaticCookiePolicy policy(false /* allow_cookies */,
+                              false /* allow_third_party_cookies */);
+  expectFirstPartyAccess(policy, false);
+  expectThirdPartyAccess(policy, false);
+}
+
+TEST_F(AwStaticCookiePolicyTest, BlockAllCookiesWithThirdPartySet) {
+  AwStaticCookiePolicy policy(false /* allow_cookies */,
+                              true  /* allow_third_party_cookies */);
+  expectFirstPartyAccess(policy, false);
+  expectThirdPartyAccess(policy, false);
+}
+
+TEST_F(AwStaticCookiePolicyTest, FirstPartyCookiesOnly) {
+  AwStaticCookiePolicy policy(true  /* allow_cookies */,
+                              false /* allow_third_party_cookies */);
+  expectFirstPartyAccess(policy, true);
+  expectThirdPartyAccess(policy, false);
+}
+
+TEST_F(AwStaticCookiePolicyTest, AllowAllCookies) {
+  AwStaticCookiePolicy policy(true /* allow_cookies */,
+                              true /* allow_third_party_cookies */);
+  expectFirstPartyAccess(policy, true);
+  expectThirdPartyAccess(policy, true);
+}
+
diff --git a/android_webview/browser/aw_web_preferences_populater.cc b/android_webview/browser/aw_web_preferences_populater.cc
new file mode 100644
index 0000000..008cf5c
--- /dev/null
+++ b/android_webview/browser/aw_web_preferences_populater.cc
@@ -0,0 +1,11 @@
+// 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 "android_webview/browser/aw_web_preferences_populater.h"
+
+namespace android_webview {
+
+AwWebPreferencesPopulater::~AwWebPreferencesPopulater() {}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_web_preferences_populater.h b/android_webview/browser/aw_web_preferences_populater.h
new file mode 100644
index 0000000..6fbd76b
--- /dev/null
+++ b/android_webview/browser/aw_web_preferences_populater.h
@@ -0,0 +1,26 @@
+// 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 ANDROID_WEBVIEW_BROWSER_AW_WEB_PREFERENCES_POPULATER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_WEB_PREFERENCES_POPULATER_H_
+
+namespace content {
+class WebContents;
+struct WebPreferences;
+}
+
+namespace android_webview {
+
+// Empty base class so this can be destroyed by AwContentBrowserClient.
+class AwWebPreferencesPopulater {
+ public:
+  virtual ~AwWebPreferencesPopulater();
+
+  virtual void PopulateFor(content::WebContents* web_contents,
+                           content::WebPreferences* web_prefs) = 0;
+};
+
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_WEB_PREFERENCES_POPULATER_H_
diff --git a/android_webview/browser/aw_web_resource_response.cc b/android_webview/browser/aw_web_resource_response.cc
new file mode 100644
index 0000000..44f2aa8
--- /dev/null
+++ b/android_webview/browser/aw_web_resource_response.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 "android_webview/browser/aw_web_resource_response.h"
+
+#include "android_webview/browser/input_stream.h"
+#include "android_webview/browser/net/android_stream_reader_url_request_job.h"
+#include "base/strings/string_number_conversions.h"
+#include "net/http/http_response_headers.h"
+
+namespace android_webview {
+
+namespace {
+
+class StreamReaderJobDelegateImpl
+    : public AndroidStreamReaderURLRequestJob::Delegate {
+ public:
+  StreamReaderJobDelegateImpl(
+      scoped_ptr<AwWebResourceResponse> aw_web_resource_response)
+      : aw_web_resource_response_(aw_web_resource_response.Pass()) {
+    DCHECK(aw_web_resource_response_);
+  }
+
+  scoped_ptr<InputStream> OpenInputStream(JNIEnv* env,
+                                          const GURL& url) override {
+    return aw_web_resource_response_->GetInputStream(env).Pass();
+  }
+
+  void OnInputStreamOpenFailed(net::URLRequest* request,
+                               bool* restart) override {
+    *restart = false;
+  }
+
+  bool GetMimeType(JNIEnv* env,
+                   net::URLRequest* request,
+                   android_webview::InputStream* stream,
+                   std::string* mime_type) override {
+    return aw_web_resource_response_->GetMimeType(env, mime_type);
+  }
+
+  bool GetCharset(JNIEnv* env,
+                  net::URLRequest* request,
+                  android_webview::InputStream* stream,
+                  std::string* charset) override {
+    return aw_web_resource_response_->GetCharset(env, charset);
+  }
+
+  void AppendResponseHeaders(JNIEnv* env,
+                             net::HttpResponseHeaders* headers) override {
+    int status_code;
+    std::string reason_phrase;
+    if (aw_web_resource_response_->GetStatusInfo(
+            env, &status_code, &reason_phrase)) {
+      std::string status_line("HTTP/1.1 ");
+      status_line.append(base::IntToString(status_code));
+      status_line.append(" ");
+      status_line.append(reason_phrase);
+      headers->ReplaceStatusLine(status_line);
+    }
+    aw_web_resource_response_->GetResponseHeaders(env, headers);
+  }
+
+ private:
+  scoped_ptr<AwWebResourceResponse> aw_web_resource_response_;
+};
+
+}  // namespace
+
+// static
+net::URLRequestJob* AwWebResourceResponse::CreateJobFor(
+    scoped_ptr<AwWebResourceResponse> aw_web_resource_response,
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate) {
+  DCHECK(aw_web_resource_response);
+  DCHECK(request);
+  DCHECK(network_delegate);
+
+  return new AndroidStreamReaderURLRequestJob(
+      request,
+      network_delegate,
+      make_scoped_ptr(
+          new StreamReaderJobDelegateImpl(aw_web_resource_response.Pass())));
+}
+
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_web_resource_response.h b/android_webview/browser/aw_web_resource_response.h
new file mode 100644
index 0000000..34963606
--- /dev/null
+++ b/android_webview/browser/aw_web_resource_response.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_BROWSER_INTERCEPTED_REQUEST_DATA_H_
+#define ANDROID_WEBVIEW_BROWSER_INTERCEPTED_REQUEST_DATA_H_
+
+#include <string>
+
+#include "base/android/jni_android.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace net {
+class HttpResponseHeaders;
+class NetworkDelegate;
+class URLRequest;
+class URLRequestJob;
+}
+
+namespace android_webview {
+
+class InputStream;
+
+// This class represents the Java-side data that is to be used to complete a
+// particular URLRequest.
+class AwWebResourceResponse {
+ public:
+  virtual ~AwWebResourceResponse() {}
+
+  virtual scoped_ptr<InputStream> GetInputStream(JNIEnv* env) const = 0;
+  virtual bool GetMimeType(JNIEnv* env, std::string* mime_type) const = 0;
+  virtual bool GetCharset(JNIEnv* env, std::string* charset) const = 0;
+  virtual bool GetStatusInfo(JNIEnv* env,
+                             int* status_code,
+                             std::string* reason_phrase) const = 0;
+  // If true is returned then |headers| contain the headers, if false is
+  // returned |headers| were not updated.
+  virtual bool GetResponseHeaders(
+      JNIEnv* env,
+      net::HttpResponseHeaders* headers) const = 0;
+
+  // This creates a URLRequestJob for the |request| wich will read data from
+  // the |aw_web_resource_response| structure (instead of going to the network
+  // or to the cache).
+  // The newly created job takes ownership of |aw_web_resource_response|.
+  static net::URLRequestJob* CreateJobFor(
+      scoped_ptr<AwWebResourceResponse> aw_web_resource_response,
+      net::URLRequest* request,
+      net::NetworkDelegate* network_delegate);
+
+ protected:
+  AwWebResourceResponse() {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AwWebResourceResponse);
+};
+
+} // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_INTERCEPTED_REQUEST_DATA_H_
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
new file mode 100644
index 0000000..4bf5e4b
--- /dev/null
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -0,0 +1,748 @@
+// Copyright 2014 The Chromium Authors. 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/browser_view_renderer.h"
+
+#include "android_webview/browser/browser_view_renderer_client.h"
+#include "android_webview/browser/child_frame.h"
+#include "base/auto_reset.h"
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "base/supports_user_data.h"
+#include "base/trace_event/trace_event_argument.h"
+#include "cc/output/compositor_frame.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
+#include "gpu/command_buffer/service/gpu_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"
+#include "third_party/skia/include/core/SkPictureRecorder.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
+
+namespace android_webview {
+
+namespace {
+
+const double kEpsilon = 1e-8;
+
+const int64 kFallbackTickTimeoutInMilliseconds = 100;
+
+// Used to calculate memory allocation. Determined experimentally.
+const size_t kMemoryMultiplier = 20;
+const size_t kBytesPerPixel = 4;
+const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
+uint64 g_memory_override_in_bytes = 0u;
+
+const void* kBrowserViewRendererUserDataKey = &kBrowserViewRendererUserDataKey;
+
+class BrowserViewRendererUserData : public base::SupportsUserData::Data {
+ public:
+  BrowserViewRendererUserData(BrowserViewRenderer* ptr) : bvr_(ptr) {}
+
+  static BrowserViewRenderer* GetBrowserViewRenderer(
+      content::WebContents* web_contents) {
+    if (!web_contents)
+      return NULL;
+    BrowserViewRendererUserData* data =
+        static_cast<BrowserViewRendererUserData*>(
+            web_contents->GetUserData(kBrowserViewRendererUserDataKey));
+    return data ? data->bvr_ : NULL;
+  }
+
+ private:
+  BrowserViewRenderer* bvr_;
+};
+
+}  // namespace
+
+// static
+void BrowserViewRenderer::CalculateTileMemoryPolicy() {
+  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
+
+  // If the value was overridden on the command line, use the specified value.
+  bool client_hard_limit_bytes_overridden =
+      cl->HasSwitch(switches::kForceGpuMemAvailableMb);
+  if (client_hard_limit_bytes_overridden) {
+    base::StringToUint64(
+        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+            switches::kForceGpuMemAvailableMb),
+        &g_memory_override_in_bytes);
+    g_memory_override_in_bytes *= 1024 * 1024;
+  }
+}
+
+// static
+BrowserViewRenderer* BrowserViewRenderer::FromWebContents(
+    content::WebContents* web_contents) {
+  return BrowserViewRendererUserData::GetBrowserViewRenderer(web_contents);
+}
+
+BrowserViewRenderer::BrowserViewRenderer(
+    BrowserViewRendererClient* client,
+    const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
+    : client_(client),
+      shared_renderer_state_(ui_task_runner, this),
+      ui_task_runner_(ui_task_runner),
+      compositor_(NULL),
+      is_paused_(false),
+      view_visible_(false),
+      window_visible_(false),
+      attached_to_window_(false),
+      hardware_enabled_(false),
+      dip_scale_(0.f),
+      page_scale_factor_(1.f),
+      min_page_scale_factor_(0.f),
+      max_page_scale_factor_(0.f),
+      on_new_picture_enable_(false),
+      clear_view_(false),
+      offscreen_pre_raster_(false),
+      fallback_tick_pending_(false) {}
+
+BrowserViewRenderer::~BrowserViewRenderer() {
+}
+
+void BrowserViewRenderer::RegisterWithWebContents(
+    content::WebContents* web_contents) {
+  web_contents->SetUserData(kBrowserViewRendererUserDataKey,
+                            new BrowserViewRendererUserData(this));
+}
+
+SharedRendererState* BrowserViewRenderer::GetAwDrawGLViewContext() {
+  return &shared_renderer_state_;
+}
+
+bool BrowserViewRenderer::RequestDrawGL(bool wait_for_completion) {
+  return client_->RequestDrawGL(wait_for_completion);
+}
+
+void BrowserViewRenderer::TrimMemory(const int level, const bool visible) {
+  DCHECK(ui_task_runner_->BelongsToCurrentThread());
+  // Constants from Android ComponentCallbacks2.
+  enum {
+    TRIM_MEMORY_RUNNING_LOW = 10,
+    TRIM_MEMORY_UI_HIDDEN = 20,
+    TRIM_MEMORY_BACKGROUND = 40,
+    TRIM_MEMORY_MODERATE = 60,
+  };
+
+  // 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;
+
+  // Nothing to drop.
+  if (!compositor_ || !hardware_enabled_)
+    return;
+
+  TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory");
+
+  // If offscreen pre-raster is disabled, drop everything in hardware. Otherwise
+  // keep the tiles and just delete the HardwareRenderer.
+  if (level >= TRIM_MEMORY_MODERATE) {
+    if (offscreen_pre_raster_)
+      shared_renderer_state_.DeleteHardwareRendererOnUI();
+    else
+      shared_renderer_state_.ReleaseHardwareDrawIfNeededOnUI();
+    return;
+  }
+
+  // Just set the memory limit to 0 and drop all tiles. This will be reset to
+  // normal levels in the next DrawGL call.
+  if (!offscreen_pre_raster_)
+    compositor_->SetMemoryPolicy(0u);
+}
+
+void BrowserViewRenderer::UpdateMemoryPolicy() {
+  if (!hardware_enabled_) {
+    compositor_->SetMemoryPolicy(0u);
+    return;
+  }
+
+  size_t bytes_limit = 0u;
+  if (g_memory_override_in_bytes) {
+    bytes_limit = static_cast<size_t>(g_memory_override_in_bytes);
+  } else {
+    ParentCompositorDrawConstraints parent_draw_constraints =
+        shared_renderer_state_.GetParentDrawConstraintsOnUI();
+    gfx::Rect interest_rect =
+        offscreen_pre_raster_ || parent_draw_constraints.is_layer
+            ? gfx::Rect(size_)
+            : last_on_draw_global_visible_rect_;
+    size_t width = interest_rect.width();
+    size_t height = interest_rect.height();
+    bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height;
+    // Round up to a multiple of kMemoryAllocationStep.
+    bytes_limit =
+        (bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep;
+  }
+
+  compositor_->SetMemoryPolicy(bytes_limit);
+}
+
+void BrowserViewRenderer::PrepareToDraw(const gfx::Vector2d& scroll,
+                                        const gfx::Rect& global_visible_rect) {
+  last_on_draw_scroll_offset_ = scroll;
+  last_on_draw_global_visible_rect_ = global_visible_rect;
+}
+
+bool BrowserViewRenderer::CanOnDraw() {
+  if (!compositor_) {
+    TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_NoCompositor",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return false;
+  }
+  if (clear_view_) {
+    TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_ClearView",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return false;
+  }
+
+  return true;
+}
+
+bool BrowserViewRenderer::OnDrawHardware() {
+  TRACE_EVENT0("and