Merge tag android-5.1.0_r1 into AOSP_5.1_MERGE

Change-Id: I1bc3ca44ee58ffd16ce2bb13d8c88dbea391662c
diff --git a/buildbot/aosp_manifest.xml b/buildbot/aosp_manifest.xml
new file mode 100644
index 0000000..bd73b30
--- /dev/null
+++ b/buildbot/aosp_manifest.xml
@@ -0,0 +1,466 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest>
+  <remote  name="aosp"
+           fetch=".."
+           review="https://android-review.googlesource.com/" />
+  <default revision="master"
+           remote="aosp"
+           sync-j="4" />
+
+  <project groups="device,flo" name="device/asus/deb" revision="0ce3a783d549d023ddc553a04fed717ffb2ff533" />
+  <project groups="device,flo" name="device/asus/flo" revision="55ea79b11f9f82b2aa03f44a3429112fc5c06d07" />
+  <project groups="device,flo" name="device/asus/flo-kernel" revision="6d74123947016999ae62d9c3067ae97782fdba21" />
+  <project groups="device,grouper" name="device/asus/grouper" revision="78fe48f44e90ef3a7eceab5465dbad63cd16ce88" />
+  <project groups="device,grouper" name="device/asus/tilapia" revision="e5033bc80764067cbb1c9dc3970f0718e35ae8c7" />
+  <project name="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30" />
+  <project groups="pdk" name="device/generic/armv7-a-neon" revision="8bcf4b7a6380b26c2b42dae00dd8443de2a8e12c" />
+  <project groups="pdk" name="device/generic/common" revision="11c092a6cbfcf6207f07a9a8e3398e747e7f5461" />
+  <project groups="pdk" name="device/generic/goldfish" revision="638ee524f83053613c47ddea22c4bf98a0175c2f" />
+  <project groups="pdk" name="device/generic/mini-emulator-armv7-a-neon" revision="2a7ade61377b7906187ab46b5859c896baa0ab0e" />
+  <project groups="pdk" name="device/generic/mini-emulator-mips" revision="2ff06dda649ba43507a911057f7854a3373ef7d6" />
+  <project groups="pdk" name="device/generic/mini-emulator-x86" revision="a2f05b8c5259c232be5b029b2d5e721ba3f70917" />
+  <project groups="pdk" name="device/generic/mips" revision="dd06e7883227cc68bb1206584c8e3a768e49d02d" />
+  <project name="device/generic/qemu" revision="bd2543e810f3fa56e9dcfe301b893832534c85db" />
+  <project groups="pdk" name="device/generic/x86" revision="f111878fb41e2bdf4eb092d1edf0eb53cc5d0153" />
+  <project groups="device" name="device/google/accessory/arduino" revision="abc5159a3ca9dbb5c7e364a1eab99901a4440ac5" />
+  <project groups="device" name="device/google/accessory/demokit" revision="7dfe7f89a3b174709c773fe319531006e46440d9" />
+  <project groups="device,hammerhead" name="device/lge/hammerhead" revision="ec229bf178b891cc18552833f2de743acf390a7c" />
+  <project groups="device,hammerhead" name="device/lge/hammerhead-kernel" revision="a1dc58be96e7a71496e3e89079ac704930f982f2" />
+  <project groups="device,mako" name="device/lge/mako" revision="7e5f0f313819ffa3b45cd4208ab552f446c33936" />
+  <project groups="device,mako" name="device/lge/mako-kernel" revision="b7de901b8cb86036e9b92b3b6f188b45a524b125" />
+  <project groups="pdk" name="device/sample" revision="096f9eb5763fd2766fcbbe4f6b9da51c87f61797" />
+  <project groups="device,manta" name="device/samsung/manta" revision="78fe248ddb214aca2215df46be83882dc50c9283" />
+  <project groups="pdk" name="platform/abi/cpp" path="abi/cpp" revision="a0f99286d0909f7a30b0bee742bec2a0b62c4dd0" />
+  <project name="platform/art" path="art" revision="36b111c7d3d635e262114dabde4c26952c7dcbe6" />
+  <project groups="pdk" name="platform/bionic" path="bionic" revision="36bacd237de931c48714d1a8aa4aa9522283e407" />
+  <project name="platform/bootable/bootloader/legacy" path="bootable/bootloader/legacy" revision="3c491d6efb8ff2534a6934702760a6273f197918" />
+  <project name="platform/bootable/diskinstaller" path="bootable/diskinstaller" revision="ca40959a8caafa0df6a5c3d845e2afe6b252093f" />
+  <project groups="pdk" name="platform/bootable/recovery" path="bootable/recovery" revision="974fe112ae6df95ca6d49688d6e3e459d87e16de" />
+  <project groups="pdk" name="platform/build" path="build" revision="d23798bfdc9bb34909177c3c5f06f0c97cc9897e" >
+    <copyfile dest="Makefile" src="core/root.mk"/>
+  </project>
+  <project groups="cts" name="platform/cts" path="cts" revision="e15e8f846e19816e18ee3293c5b99f78463be28e" />
+  <project name="platform/dalvik" path="dalvik" revision="fb5b0d5bc46bce9c8ed6b1150498d6e145811a7d" />
+  <project name="platform/developers/build" path="developers/build" revision="75c5c41b06f045c3304b1b19d8250f04a8da8f10" />
+  <project name="platform/developers/demos" path="developers/demos" revision="64526120cd8da89bcb9a48acf95307d2c172a6e8" />
+  <project name="platform/developers/docs" path="developers/docs" revision="c0b835ddd9acc27176dc9a0f7d1aa2faf5d51806" />
+  <project name="platform/developers/samples/android" path="developers/samples/android" revision="dea82fa23f038d66bd9cfdff2afb8ef22add1c4f" />
+  <project name="platform/development" path="development" revision="0efeb2c66bff9b36feecd9315d14d2afb46e4669" />
+  <project name="platform/docs/source.android.com" path="docs/source.android.com" revision="c4795fa0df2c5fb4832ae65482944e8e5400e4f6" />
+  <project groups="pdk" name="platform/external/aac" path="external/aac" revision="35f30c5ab8089f38681d2fdd416c00aebef5a7ff" />
+  <project name="platform/external/android-clat" path="external/android-clat" revision="18921713780edb45ceef327d5fcf3387818300f3" />
+  <project name="platform/external/android-mock" path="external/android-mock" revision="4fe497660c2e939300dc5b743d662aef458b1726" />
+  <project name="platform/external/ant-glob" path="external/ant-glob" revision="0f189400fd2a36bf11bfb058e7f3917eb7ed163a" />
+  <project name="platform/external/antlr" path="external/antlr" revision="47997265eeb7d954a32ece693bbe6dab740872dd" />
+  <project name="platform/external/apache-harmony" path="external/apache-harmony" revision="6942e08fdbbd8402c9deabb0f60c8c871194b244" />
+  <project name="platform/external/apache-http" path="external/apache-http" revision="85ed0e10781c3c57343300a02556dd5131c450aa" />
+  <project name="platform/external/apache-qp" path="external/apache-qp" revision="64ea622b23e6612eb8e7dcae6bfd4314beb022a8" />
+  <project name="platform/external/apache-xml" path="external/apache-xml" revision="00ee83ff1bd827a852065986ed0da7a3ded57a55" />
+  <project name="platform/external/arduino" path="external/arduino" revision="d06daf9bbc46838400461eb8e15842974e38d82a" />
+  <project groups="pdk" name="platform/external/bison" path="external/bison" revision="c2418b886165add7f5a31fc5609f0ce2d004a90e" />
+  <project name="platform/external/blktrace" path="external/blktrace" revision="d345431f16b8f76f30a58193ff2b26d5853e1109" />
+  <project groups="pdk" name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="3b4040093ddf0e0025d0dd034aa65078bb695514" />
+  <project name="platform/external/bouncycastle" path="external/bouncycastle" revision="234720ebe66540a53cff98b2448dddbc884bd09f" />
+  <project groups="pdk" name="platform/external/bsdiff" path="external/bsdiff" revision="6f503758fad2cbcf8359e8f0af32e4d79a2a48ae" />
+  <project groups="pdk" name="platform/external/bzip2" path="external/bzip2" revision="1cb636bd8e9e5cdfd5d5b2909a122f6e80db62de" />
+  <project name="platform/external/ceres-solver" path="external/ceres-solver" revision="399f7d09e0c45af54b77b4ab9508d6f23759b927" />
+  <project groups="pdk" name="platform/external/checkpolicy" path="external/checkpolicy" revision="c66ac590eebc731f6021f267ebea208e87d8f04f" />
+  <project name="platform/external/chromium" path="external/chromium" revision="f294081d501ad98b7d7f50bc73f291063caf2c5f" />
+  <project name="platform/external/chromium-libpac" path="external/chromium-libpac" revision="09cf45bf5a650fe1abd50b9d61c2670a62f62767" />
+  <project groups="pdk" name="platform/external/chromium-trace" path="external/chromium-trace" revision="8252ae6b83ea65cf871e7981e981da07379f5a0f" />
+  <project name="platform/external/chromium_org" path="external/chromium_org" revision="43165a58c6167882aabb62f470c4e4d21f807d79" />
+  <project name="platform/external/chromium_org/sdch/open-vcdiff" path="external/chromium_org/sdch/open-vcdiff" revision="6d634da5463d9bc5fc88f86aec1d2ac4fe6f612e" />
+  <project name="platform/external/chromium_org/testing/gtest" path="external/chromium_org/testing/gtest" revision="65df883d09205766c521f2e6c126f4070a423141" />
+  <project name="platform/external/chromium_org/third_party/WebKit" path="external/chromium_org/third_party/WebKit" revision="a25b4978c2c50d573391a6d56a0e8ad35f52ffc8" />
+  <project name="platform/external/chromium_org/third_party/angle" path="external/chromium_org/third_party/angle" revision="8b77c2b2231f7d895979f6341e1ad1964a654ce4" />
+  <project name="platform/external/chromium_org/third_party/boringssl/src" path="external/chromium_org/third_party/boringssl/src" revision="85fb7432d3c851200342dd982b211f8dac860687" />
+  <project name="platform/external/chromium_org/third_party/brotli/src" path="external/chromium_org/third_party/brotli/src" revision="96f298ac43a9216b251d6c3264d8f5ada89e107f" />
+  <project name="platform/external/chromium_org/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille" path="external/chromium_org/third_party/eyesfree/src/android/java/src/com/googlecode/eyesfree/braille" revision="bb4c72f1deb0b8b2b0468b0bf1050462ebcf6135" />
+  <project name="platform/external/chromium_org/third_party/freetype" path="external/chromium_org/third_party/freetype" revision="dc263f2ee2786739da036911ed8b29c07a639ab9" />
+  <project name="platform/external/chromium_org/third_party/icu" path="external/chromium_org/third_party/icu" revision="85e5871666cade1bb4b53f0cebfae53bc7d8d1f2" />
+  <project name="platform/external/chromium_org/third_party/leveldatabase/src" path="external/chromium_org/third_party/leveldatabase/src" revision="d4e10f2a91f5de7bd17adcdbd80c54b19ab336fe" />
+  <project name="platform/external/chromium_org/third_party/libaddressinput/src" path="external/chromium_org/third_party/libaddressinput/src" revision="7127f6844fac19d7610e34f4f7e03398fcd95531" />
+  <project name="platform/external/chromium_org/third_party/libjingle/source/talk" path="external/chromium_org/third_party/libjingle/source/talk" revision="8fd7b6a4d9e6757c5e1ff50147e6089979bf6701" />
+  <project name="platform/external/chromium_org/third_party/libphonenumber/src/phonenumbers" path="external/chromium_org/third_party/libphonenumber/src/phonenumbers" revision="de6af28b9f9f34a31ffb7772b7510fd215a0814e" />
+  <project name="platform/external/chromium_org/third_party/libphonenumber/src/resources" path="external/chromium_org/third_party/libphonenumber/src/resources" revision="8f194ead1ebd76ebb28b7e2dfc0a7baddc62bb22" />
+  <project name="platform/external/chromium_org/third_party/libsrtp" path="external/chromium_org/third_party/libsrtp" revision="5eddd5b3436aa8b2c7eb1f3c6db154281c6b91c5" />
+  <project name="platform/external/chromium_org/third_party/libvpx" path="external/chromium_org/third_party/libvpx" revision="c20d6540c47e427470c5a56b35fea3c5e9098748" />
+  <project name="platform/external/chromium_org/third_party/libyuv" path="external/chromium_org/third_party/libyuv" revision="6e77b766a9eb7889c1a10cab978705ffe03ff3e7" />
+  <project name="platform/external/chromium_org/third_party/mesa/src" path="external/chromium_org/third_party/mesa/src" revision="e70a8ff30d20e1bf6bb5c06b5cd7bd4ea9ae20e1" />
+  <project name="platform/external/chromium_org/third_party/openmax_dl" path="external/chromium_org/third_party/openmax_dl" revision="83d0254a412b93e81b06a354b90fb627408b4ec8" />
+  <project name="platform/external/chromium_org/third_party/openssl" path="external/chromium_org/third_party/openssl" revision="c2a9402712e13e15fcae2b17ec0cbecb816ef52e" />
+  <project name="platform/external/chromium_org/third_party/opus/src" path="external/chromium_org/third_party/opus/src" revision="e383b38591b010ab08ebddf1fd8d821796bd961a" />
+  <project name="platform/external/chromium_org/third_party/ots" path="external/chromium_org/third_party/ots" revision="4d6e4ddc4b0db2023b1380236c33aa04a7e9e927" />
+  <project name="platform/external/chromium_org/third_party/sfntly/cpp/src" path="external/chromium_org/third_party/sfntly/cpp/src" revision="2bac2ec7167835b214bfe42e762cd2ce6cf8cf1a" />
+  <project name="platform/external/chromium_org/third_party/skia" path="external/chromium_org/third_party/skia" revision="2d75d0865c7bac54bf5e234855609d0f628388b7" />
+  <project name="platform/external/chromium_org/third_party/smhasher/src" path="external/chromium_org/third_party/smhasher/src" revision="09e3094b8ab52bb1ad9ab8c8351d99df50327b67" />
+  <project name="platform/external/chromium_org/third_party/usrsctp/usrsctplib" path="external/chromium_org/third_party/usrsctp/usrsctplib" revision="ed9a6fb519aa7606cab965b2c4218756e849ddb6" />
+  <project name="platform/external/chromium_org/third_party/webrtc" path="external/chromium_org/third_party/webrtc" revision="8b45a80ec9c21b148a5674d3a23ca5fa70981f71" />
+  <project name="platform/external/chromium_org/third_party/yasm/source/patched-yasm" path="external/chromium_org/third_party/yasm/source/patched-yasm" revision="0f308c9bc9aa3258a0e90285b9d4e69bbb5b0a73" />
+  <project name="platform/external/chromium_org/tools/grit" path="external/chromium_org/tools/grit" revision="4ad93ed16c8ae7742fd7c34c83036b8d03c21fb9" />
+  <project name="platform/external/chromium_org/tools/gyp" path="external/chromium_org/tools/gyp" revision="9c42a79388ce87185ad04cb02047c1e56ac5e066" />
+  <project name="platform/external/chromium_org/v8" path="external/chromium_org/v8" revision="db865e6839e98cc9d07609bf81bb6610117ba6ff" />
+  <project groups="pdk" name="platform/external/clang" path="external/clang" revision="070ed154a0a8bc2c0fd4fb9b8a86a0f1218e6dfa" />
+  <project groups="pdk" name="platform/external/compiler-rt" path="external/compiler-rt" revision="c185902e393cd71823258016ead1b315ed062b24" />
+  <project name="platform/external/conscrypt" path="external/conscrypt" revision="26163c268a6d2625384b87e907afad8ef19f9a47" />
+  <project name="platform/external/dexmaker" path="external/dexmaker" revision="2b528c4b156f2de5c641875b98e59e0b09ebaccd" />
+  <project name="platform/external/dhcpcd" path="external/dhcpcd" revision="03baf5eab896198b5060d287af3fd60d360bf48f" />
+  <project groups="pdk" name="platform/external/dnsmasq" path="external/dnsmasq" revision="7674911bc9d10adf57c2c2d15d0c641b48e4afe6" />
+  <project name="platform/external/doclava" path="external/doclava" revision="b9d279d8f9c29a3044d13482846efb21f27b5df4" />
+  <project groups="pdk" name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="721f3bc56989b5f4101e646a02d598ddb4a7ff6e" />
+  <project name="platform/external/easymock" path="external/easymock" revision="c9a234086537e5fd820b110bbd99e3cdc695004c" />
+  <project name="platform/external/eclipse-basebuilder" path="external/eclipse-basebuilder" revision="6134da6347cc997e0cf2921aaadfb46f21c05d85" />
+  <project name="platform/external/eclipse-windowbuilder" path="external/eclipse-windowbuilder" revision="a5f3ee137e94737538ec3bdf9b3716765d178c17" />
+  <project name="platform/external/eigen" path="external/eigen" revision="b015e75e8c7ba1ab4ddb91e9372a57e76f3fd159" />
+  <project name="platform/external/elfutils" path="external/elfutils" revision="38ecac0276825a9463803485440646582e477e78" />
+  <project name="platform/external/embunit" path="external/embunit" revision="336b7c65098af0d1be69f2db55f4e75342d73b3f" />
+  <project name="platform/external/emma" path="external/emma" revision="daacd02a6b9f7a3e82bdf1cc5b84db85ed59edb1" />
+  <project name="platform/external/esd" path="external/esd" revision="224a67f2683a7ee997179fc5dd16115e39987b0f" />
+  <project groups="pdk" name="platform/external/expat" path="external/expat" revision="907ec055718996baf36961e7f47f8447e49b3865" />
+  <project name="platform/external/eyes-free" path="external/eyes-free" revision="16bd4c7a4d1bfe229068b637614dad7c48dd2ceb" />
+  <project name="platform/external/f2fs-tools" path="external/f2fs-tools" revision="00dc8a1c6c87acf687e64e66cfc2fd7ca28e646e" />
+  <project name="platform/external/fdlibm" path="external/fdlibm" revision="c831c726067e0d8a05362e710e2405f0eff81e07" />
+  <project name="platform/external/fio" path="external/fio" revision="6f4e805b805f1ab3025482e471147bb51efa99bd" />
+  <project groups="pdk" name="platform/external/flac" path="external/flac" revision="7f32dd57579bdff88e46e1e403154be0b99165da" />
+  <project groups="pdk" name="platform/external/freetype" path="external/freetype" revision="899c67b6cfcd2010784fbf08c5415af16c526e0c" />
+  <project name="platform/external/fsck_msdos" path="external/fsck_msdos" revision="17a1471db8c528cd9d44ec4385d2eb3614138856" />
+  <project name="platform/external/ganymed-ssh2" path="external/ganymed-ssh2" revision="d3724dabc1cfbacd105fe6c422b4dcba80e4fb2d" />
+  <project groups="pdk" name="platform/external/gcc-demangle" path="external/gcc-demangle" revision="9241386b62c353302c2f9eccda0672685b252b4d" />
+  <project name="platform/external/genext2fs" path="external/genext2fs" revision="e11a9c7fe6f1cef99aad2f25afaea37b72fe9f93" />
+  <project name="platform/external/giflib" path="external/giflib" revision="621696a283c0ce34956417f760f1005fadcd12ae" />
+  <project name="platform/external/google-diff-match-patch" path="external/google-diff-match-patch" revision="cecbe12841337860291c2d6a5728b681ec5fca2a" />
+  <project name="platform/external/google-fonts/carrois-gothic-sc" path="external/google-fonts/carrois-gothic-sc" revision="0062a10458d4c357f3082d66bcb129d11913aaae" />
+  <project name="platform/external/google-fonts/coming-soon" path="external/google-fonts/coming-soon" revision="2c5cb418c690815545bbb0316eae5fd33b9fc859" />
+  <project name="platform/external/google-fonts/dancing-script" path="external/google-fonts/dancing-script" revision="7b6623bd54cee3e48ae8a4f477f616366643cc78" />
+  <project name="platform/external/grub" path="external/grub" revision="33a4e7e4cfa81dc21d37091515891859ef3ab934" />
+  <project groups="pdk" name="platform/external/gtest" path="external/gtest" revision="fa3c26b862ca17c0d2db67606226b49d1648b4bf" />
+  <project name="platform/external/guava" path="external/guava" revision="5e6db342fc75b1945298142530f2d1d1861bce73" />
+  <project name="platform/external/hamcrest" path="external/hamcrest" revision="ba28ac1e0386f26d9a45be5ed16fc9c598b27e70" />
+  <project name="platform/external/harfbuzz" path="external/harfbuzz" revision="7a08026033b424da3b7022ebcce35f033949df8b" />
+  <project name="platform/external/harfbuzz_ng" path="external/harfbuzz_ng" revision="3e537b48a7b56c742ecf3c2ed24ff15fcb73f575" />
+  <project name="platform/external/hyphenation" path="external/hyphenation" revision="bfa84834dfeb7fe8d058c2e7e07b5981451ddf82" />
+  <project name="platform/external/icu" path="external/icu" revision="3c09e2ebbdae6000f3bd471c34d055bc1913f7e4" />
+  <project groups="pdk" name="platform/external/icu4c" path="external/icu4c" revision="e5311394ca22b280da41cd17059288dab3fb1ea6" />
+  <project groups="pdk" name="platform/external/iproute2" path="external/iproute2" revision="5d4c86892885ae1bc12e0e157b35ef44e8ba81bd" />
+  <project name="platform/external/ipsec-tools" path="external/ipsec-tools" revision="f4cb1ee4b00abbfb6f968dc25818c23b4b47e584" />
+  <project name="platform/external/iptables" path="external/iptables" revision="e3928b77f18db0fdc615693017c6c15eb71bf4e0" />
+  <project name="platform/external/iputils" path="external/iputils" revision="1c7c426ab377c3a005a36d612ebbb16de86fb7d4" />
+  <project name="platform/external/jack" path="external/jack" revision="5ceb2025ac5d25ed48183ac2d3dac4691fe761fb" />
+  <project name="platform/external/javasqlite" path="external/javasqlite" revision="b8501bdeb0b7e39a0d82f2a96ad382c05a763b22" />
+  <project name="platform/external/javassist" path="external/javassist" revision="9566207cff5871c672fac1f0d4332d93292036d7" />
+  <project name="platform/external/jdiff" path="external/jdiff" revision="e4694302d6a3786c64d954e0b3cf42786283bd3c" />
+  <project name="platform/external/jemalloc" path="external/jemalloc" revision="615fe54259e545c33275753a316c2bfd1198b4f0" />
+  <project groups="pdk" name="platform/external/jhead" path="external/jhead" revision="871af5c305ce1d3087e58fae091c60c359f5fa45" />
+  <project name="platform/external/jmdns" path="external/jmdns" revision="f4eb7466d5c09098f9dc54137ed3235e3c43fc9f" />
+  <project name="platform/external/jmonkeyengine" path="external/jmonkeyengine" revision="a6b44658eb1c55295f132a36233a11aa2bd8f9cf" />
+  <project groups="pdk" name="platform/external/jpeg" path="external/jpeg" revision="213197252c8c4825f6572c651126c22067025fe9" />
+  <project name="platform/external/jsilver" path="external/jsilver" revision="739060b01245f1dc5f1800949b3c30c291253cff" />
+  <project name="platform/external/jsr305" path="external/jsr305" revision="a82868820d6350811b9ddfde4bf8ed5016084269" />
+  <project name="platform/external/junit" path="external/junit" revision="8f312e0c3d6dff30d015d2c85fdaae0a39220fd6" />
+  <project name="platform/external/kernel-headers" path="external/kernel-headers" revision="8b663ef01dcaadfe1dec7ba826e5cd1cf0bb2c91" />
+  <project name="platform/external/libcap-ng" path="external/libcap-ng" revision="1d1011a3c5049a7f9eef99d22f3704e4367579cc" />
+  <project name="platform/external/libcxx" path="external/libcxx" revision="a9aa30b5d18422fce29a42ce1a704bc5f28febde" />
+  <project name="platform/external/libcxxabi" path="external/libcxxabi" revision="87a9be28aceed80250cd1d1a47eb8afa0ee67b51" />
+  <project name="platform/external/libcxxrt" path="external/libcxxrt" revision="d1ee2b2a4946a073596514462d7629373d22fb27" />
+  <project name="platform/external/libexif" path="external/libexif" revision="25d371312cee1452a2adcf8b7f6cad6267bda32d" />
+  <project name="platform/external/libffi" path="external/libffi" revision="385ba8b006b9995456d3c9283fd20dded90809cc" />
+  <project groups="pdk" name="platform/external/libgsm" path="external/libgsm" revision="50761abed8f4734970874165b386cfd4d9599db4" />
+  <project groups="pdk" name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb" />
+  <project name="platform/external/libmtp" path="external/libmtp" revision="7075348937f6a8c9d9211942fcb6c376f4227776" />
+  <project groups="pdk" name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="46abb3dcf960058e48d1444b6a11cc7e84912339" />
+  <project groups="pdk" name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="15d81f71a668b3092549c6b7f83694bf680d9c49" />
+  <project name="platform/external/libnl" path="external/libnl" revision="99debfa4c01b49c9b470884cc56f81fcdee0fa1f" />
+  <project groups="pdk" name="platform/external/libnl-headers" path="external/libnl-headers" revision="52c926a9de955fa2d987bf8c5d4a1304b5a2a611" />
+  <project name="platform/external/libogg" path="external/libogg" revision="ec0b24fb1468abe37be4164a6feb16568e036bde" />
+  <project name="platform/external/libpcap" path="external/libpcap" revision="9dab0cd7430a4d23e0a7752fb13b941692171c3d" />
+  <project name="platform/external/libphonenumber" path="external/libphonenumber" revision="485e6d5c6e48a1fc43cc0a090e687c723dac056c" />
+  <project groups="pdk" name="platform/external/libpng" path="external/libpng" revision="48b7ba25a15a9eae83d366c02475539725d035d0" />
+  <project name="platform/external/libppp" path="external/libppp" revision="706e567fc5ff6b79738a5f470e5aa7b2cae76459" />
+  <project name="platform/external/libseccomp-helper" path="external/libseccomp-helper" revision="e87019943a8b5a7cd0880910f671c37b240d5754" />
+  <project groups="pdk" name="platform/external/libselinux" path="external/libselinux" revision="da4208c8808e6a62fcfe848343abd3e2f3b339cc" />
+  <project groups="pdk" name="platform/external/libsepol" path="external/libsepol" revision="d26204e7d0a3be178a97d4920b82007e05a2a632" />
+  <project name="platform/external/libssh2" path="external/libssh2" revision="2bb40f2445cab3ba588efb29e1835cdba2b27248" />
+  <project name="platform/external/libunwind" path="external/libunwind" revision="b3436a3feed4dcb22dafc8f7818b742cacaddd1d" />
+  <project name="platform/external/libusb" path="external/libusb" revision="2801917fe150393d4f4a354165fe89550ae22613" />
+  <project name="platform/external/libusb-compat" path="external/libusb-compat" revision="94867ba54eb7faa8efca81cf2214d00bb9143d27" />
+  <project name="platform/external/libvorbis" path="external/libvorbis" revision="de559619fd4dd0d2d9608436696fd44bdf74eba8" />
+  <project groups="pdk" name="platform/external/libvpx" path="external/libvpx" revision="d64f247f64fbb814c9ecf06a56bcb0948bfca21f" />
+  <project name="platform/external/libxml2" path="external/libxml2" revision="399e808f940777d18efe377bd34f738dc84729e0" />
+  <project name="platform/external/libxslt" path="external/libxslt" revision="98f5140c33273d3bd67ca03566f8417406001016" />
+  <project groups="libyuv" name="platform/external/libyuv" path="external/libyuv" revision="482a582884351288fb701532359652970b1ba7c0" />
+  <project name="platform/external/linux-tools-perf" path="external/linux-tools-perf" revision="3e1937964f6c183eb6a0000e2dca27fc3a419ca2" />
+  <project name="platform/external/littlemock" path="external/littlemock" revision="328b01eada8965cd38feea884d4080c31e3763b0" />
+  <project groups="pdk" name="platform/external/llvm" path="external/llvm" revision="c4c1f81ae1b07138df50e0459631abf3082bda9c" />
+  <project name="platform/external/ltrace" path="external/ltrace" revision="82ae18484c7b6a8af05354caf6de3a7f1ac5fcf9" />
+  <project name="platform/external/lzma" path="external/lzma" revision="19cf4f773361c09e47a2ffe1613d66cbf632227f" />
+  <project name="platform/external/marisa-trie" path="external/marisa-trie" revision="629ed059b1e85cd8e4de363d8b3dc53c15c3e08a" />
+  <project name="platform/external/markdown" path="external/markdown" revision="6f2e3554ae38cc90518d32e02cb57d05988270a6" />
+  <project groups="pdk" name="platform/external/mdnsresponder" path="external/mdnsresponder" revision="b25c2507ecc3f674e3b4f0a770acf9ad8fd874d0" />
+  <project name="platform/external/mesa3d" path="external/mesa3d" revision="97d3f36a59ea448fa77e47a90bf04f1254670542" />
+  <project name="platform/external/messageformat" path="external/messageformat" revision="180a28770171075aa484729a69d14c7cf0c93fcf" />
+  <project groups="pdk" name="platform/external/mksh" path="external/mksh" revision="2a54bce0ae98f53f0b867e949b26d081691e1493" />
+  <project name="platform/external/mockito" path="external/mockito" revision="4d0dcd53b27a243baf72ee0b127b188a058b318d" />
+  <project name="platform/external/mockwebserver" path="external/mockwebserver" revision="2f7659c426de53122ee7922b0981058a900124a7" />
+  <project name="platform/external/mp4parser" path="external/mp4parser" revision="16051e950485c6b62127c0446a760111de1a0cb9" />
+  <project name="platform/external/mtpd" path="external/mtpd" revision="5ea8006691664b7e6d46d6a6dc889eac91b7fe37" />
+  <project name="platform/external/naver-fonts" path="external/naver-fonts" revision="3bba7d2430bc3ec8105678a27f03fb080f0f8384" />
+  <project name="platform/external/netcat" path="external/netcat" revision="444644cfa9a2f3002863caa168fb2d6b34dfd1e8" />
+  <project name="platform/external/netperf" path="external/netperf" revision="38e47cd883738cb84bdb47a7d263f14f14062d7b" />
+  <project name="platform/external/neven" path="external/neven" revision="504ee5ccaabd8bce4da3430b0f4e9714ac2a8e6c" />
+  <project name="platform/external/nfacct" path="external/nfacct" revision="6f7aae0264821b44e9fe80fb5596c525d3e2f475" />
+  <project name="platform/external/nist-pkits" path="external/nist-pkits" revision="b7a53ad5a587926cb880d9bb6f3d51657596474c" />
+  <project name="platform/external/nist-sip" path="external/nist-sip" revision="b23dbfce7ea84c39cea75b612868a5832cb9af2b" />
+  <project name="platform/external/noto-fonts" path="external/noto-fonts" revision="90372d894b5d9c9f2a111315d2eb3b8de1979ee4" />
+  <project name="platform/external/oauth" path="external/oauth" revision="bc170f58de82000ed6460f111686a850a1890c07" />
+  <project name="platform/external/objenesis" path="external/objenesis" revision="2a7655c0d503fcf5989098f65bf89eae78c32e5a" />
+  <project name="platform/external/okhttp" path="external/okhttp" revision="4909663c795d974d0d4b0e2d1ebd6e179486c897" />
+  <project name="platform/external/open-vcdiff" path="external/open-vcdiff" revision="6d29f2f083baf8250db94ed0b4807e513a84163d" />
+  <project name="platform/external/opencv" path="external/opencv" revision="4a99e243b42afcb885d036bb451eb3c2739275b6" />
+  <project name="platform/external/openfst" path="external/openfst" revision="b7434caa51427a0f5ab5c807e1a92d6ca2af8884" />
+  <project name="platform/external/openssh" path="external/openssh" revision="3c335c9fb9c12375ad62748fa1d1e5ebe4710c94" />
+  <project groups="pdk" name="platform/external/openssl" path="external/openssl" revision="cfe73257599ae4baae3ffb50c2c841d9249d2d16" />
+  <project name="platform/external/oprofile" path="external/oprofile" revision="3722f1053f4cab90c4daf61451713a2d61d79c71" />
+  <project name="platform/external/owasp/sanitizer" path="external/owasp/sanitizer" revision="6a304233f9f2010821a5a1dd40e2832b68353a3c" />
+  <project name="platform/external/pcre" path="external/pcre" revision="993a14b71c8e7af03eb929d44a444137393a5324" />
+  <project name="platform/external/pixman" path="external/pixman" revision="afd5bbd8074cedec8544d07920fa06786d5a4f08" />
+  <project name="platform/external/ppp" path="external/ppp" revision="8b58d9bd02e2c55f547fafbe9ba55b1160665761" />
+  <project groups="pdk-java" name="platform/external/proguard" path="external/proguard" revision="3fd19dba2bdc0c4b64afda4d75836e1dcf7abf97" />
+  <project groups="pdk" name="platform/external/protobuf" path="external/protobuf" revision="95d99df4574c28debcf9646056a0350ff44bc7c9" />
+  <project name="platform/external/qemu" path="external/qemu" revision="539e1f25ecbfe80814dba2ea77feb22087b9d53b" />
+  <project name="platform/external/qemu-pc-bios" path="external/qemu-pc-bios" revision="20349dae98d7de09a7e390d4a706c64f1db6edc2" />
+  <project name="platform/external/regex-re2" path="external/regex-re2" revision="0d4c52358a1af421705c54bd8a9fdd8a30558a2e" />
+  <project name="platform/external/replicaisland" path="external/replicaisland" revision="99e2e54c5d036048caf09bb05eea0969de093104" />
+  <project name="platform/external/robolectric" path="external/robolectric" revision="6bf395c984ed3f69711663b006aeffbb0f7e8a90" />
+  <project groups="pdk" name="platform/external/safe-iop" path="external/safe-iop" revision="aa0725fb1da35e47676b6da30009322eb5ed59be" />
+  <project groups="pdk" name="platform/external/scrypt" path="external/scrypt" revision="dde037b82e5cd6215244e3240dbaad417928eafa" />
+  <project groups="pdk" name="platform/external/sepolicy" path="external/sepolicy" revision="21ada26daea538397029396099dce865267bae2f" />
+  <project name="platform/external/sfntly" path="external/sfntly" revision="6723e5241a45c6de224c96384a595a1bf5bc5449" />
+  <project name="platform/external/sil-fonts" path="external/sil-fonts" revision="795a2f4339f8a82d6cff187e2a77bb01d5911aac" />
+  <project name="platform/external/skia" path="external/skia" revision="d6f2c76fdb9b0469261fa2db0b29ed48c7ac38b5" />
+  <project name="platform/external/smack" path="external/smack" revision="d7955ce24d294fb2014c59d11fca184471056f44" />
+  <project name="platform/external/smali" path="external/smali" revision="5fd395796e215a80c722815bf180728948868f18" />
+  <project groups="pdk" name="platform/external/sonivox" path="external/sonivox" revision="c0723d864b10fbd6c5cbbfa65e886c5e9eb3aafd" />
+  <project groups="pdk" name="platform/external/speex" path="external/speex" revision="eaa4765b8cc6a6dd5ee0d26dc1b61a1044817f32" />
+  <project groups="pdk" name="platform/external/sqlite" path="external/sqlite" revision="50af37d784661b2d54c8e043de52ffc4f02a1a50" />
+  <project name="platform/external/srec" path="external/srec" revision="540e7ee8dbf1d7ee72ef45c92efbebcb89bf6d1a" />
+  <project name="platform/external/srtp" path="external/srtp" revision="98bd63b48a31b4633cdfdc8138577dfa6d8dd2a6" />
+  <project groups="pdk" name="platform/external/stlport" path="external/stlport" revision="dc05ca5be2319f74b41cb429ea50f30fceff4ace" />
+  <project name="platform/external/strace" path="external/strace" revision="a2adbed6e2d3ce85ebb167e16ae370681a8b5188" />
+  <project name="platform/external/stressapptest" path="external/stressapptest" revision="0956427aa995561acb4471764158ae057a36dad5" />
+  <project name="platform/external/svox" path="external/svox" revision="ad0a55bd0e13a27ed11034346eee9c47e3684ef2" />
+  <project name="platform/external/syspatch" path="external/syspatch" revision="358a4f86b8c2cb3d3f879a37f6773dd09d4b77b0" />
+  <project name="platform/external/tagsoup" path="external/tagsoup" revision="a97828cb3f8f3a1af8470e55d3c5cd62d6a7cb4c" />
+  <project name="platform/external/tcpdump" path="external/tcpdump" revision="de49cdcfddf36f2b41ef3278e98a8a550a189952" />
+  <project name="platform/external/timezonepicker-support" path="external/timezonepicker-support" revision="99e91a76fd74bad10266623d67cdb98d011f709e" />
+  <project groups="pdk" name="platform/external/tinyalsa" path="external/tinyalsa" revision="653e7a4015341c87b4d55ec9a94ec7bdee044f6f" />
+  <project groups="pdk" name="platform/external/tinycompress" path="external/tinycompress" revision="aeee2c6a19b9d3765f72bc79555005786a424233" />
+  <project groups="pdk" name="platform/external/tinyxml" path="external/tinyxml" revision="f065a8058659c0e6c5a5ccddcdb4faf0fe645cd0" />
+  <project groups="pdk" name="platform/external/tinyxml2" path="external/tinyxml2" revision="c74b546f5af36968ffa56d7fd4529f4273b96f48" />
+  <project groups="pdk" name="platform/external/tremolo" path="external/tremolo" revision="0fec2aefa8143c83df43752bb0218dfa371cc57e" />
+  <project groups="pdk" name="platform/external/valgrind" path="external/valgrind" revision="893257d6c86a18cc5cf6c92528b7027f327dca70" />
+  <project name="platform/external/vixl" path="external/vixl" revision="e1ab25cde167109efb28fa6a86d5c2c80b762d58" />
+  <project name="platform/external/webp" path="external/webp" revision="0db01fc3411621bec473d50db0071fd2a225962e" />
+  <project groups="pdk" name="platform/external/webrtc" path="external/webrtc" revision="d62aeac391d16d4953a12120c0ff614ccde02a30" />
+  <project groups="pdk" name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="88ef20ce4facae68a3e6b05429bb9f3f73a93996" />
+  <project name="platform/external/xdelta3" path="external/xdelta3" revision="52d9c642e6a307c43881f20a4ed1c10e947234ba" />
+  <project name="platform/external/xmlwriter" path="external/xmlwriter" revision="e95d92246ee35273dde2bee8b00485cc14c12be5" />
+  <project name="platform/external/xmp_toolkit" path="external/xmp_toolkit" revision="42ea4dc6d1fc2206a7778029070ed9213e3b0fbf" />
+  <project groups="pdk" name="platform/external/yaffs2" path="external/yaffs2" revision="a2cff2275e1b501ff478b03757d6e4f05fddc2db" />
+  <project groups="pdk" name="platform/external/zlib" path="external/zlib" revision="8d977782c1cfe9d75cc9a464439c2ff1e27e1665" />
+  <project name="platform/external/zxing" path="external/zxing" revision="7620644768ffc235607b3a94671e49518c18686f" />
+  <project groups="pdk" name="platform/frameworks/av" path="frameworks/av" revision="a018cd4926460f8f5ab30a9a11df9775572d8620" />
+  <project name="platform/frameworks/base" path="frameworks/base" revision="6a58309e734086a21580dd8d9175ac1817ca3ab2" />
+  <project groups="pdk" name="platform/frameworks/compile/libbcc" path="frameworks/compile/libbcc" revision="3fc91521640692f844aece8b1743c4df702d1c66" />
+  <project groups="pdk" name="platform/frameworks/compile/mclinker" path="frameworks/compile/mclinker" revision="e673be8f0526f9cbc83093fb579c0f76de9e4e3c" />
+  <project groups="pdk" name="platform/frameworks/compile/slang" path="frameworks/compile/slang" revision="c957dd47b0a0705a686896b26cd1859d25824552" />
+  <project name="platform/frameworks/ex" path="frameworks/ex" revision="3696df848aa7c574f913c97c3bf415b634934048" />
+  <project name="platform/frameworks/mff" path="frameworks/mff" revision="b9669b8540a1e5c953374d53b115514335e23c27" />
+  <project name="platform/frameworks/ml" path="frameworks/ml" revision="b020ad88ca28ada76a596b5dcc7e6c2854fcc132" />
+  <project name="platform/frameworks/multidex" path="frameworks/multidex" revision="590a07e63868f0a1da311ff22b4a9f35eb48a865" />
+  <project groups="pdk" name="platform/frameworks/native" path="frameworks/native" revision="e8878921db4a51ff5d4e75d9c8958d889a048603" />
+  <project name="platform/frameworks/opt/calendar" path="frameworks/opt/calendar" revision="03b18577f8f8f799e87a62b8e03889ddacf6daa2" />
+  <project name="platform/frameworks/opt/carddav" path="frameworks/opt/carddav" revision="f08aa2df132dd8dc32a0013d3750137d9dd9280a" />
+  <project name="platform/frameworks/opt/colorpicker" path="frameworks/opt/colorpicker" revision="720a40ae24d526268b3c0f2dd8497b5df2cc6f23" />
+  <project name="platform/frameworks/opt/datetimepicker" path="frameworks/opt/datetimepicker" revision="8a1c55baaf5ced7a98b196c689ccdd59238f6e58" />
+  <project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="709f713ebcd62c61defc270d945810efca179621" />
+  <project name="platform/frameworks/opt/inputmethodcommon" path="frameworks/opt/inputmethodcommon" revision="df9dd39c2047992a43b64e13bb0fc348a1630f3b" />
+  <project name="platform/frameworks/opt/mailcommon" path="frameworks/opt/mailcommon" revision="1537812900e59f875cfea0483f0ae261b16d3e4b" />
+  <project name="platform/frameworks/opt/mms" path="frameworks/opt/mms" revision="64817e848552fd0a429a3e026b7b1562103c56bb" />
+  <project name="platform/frameworks/opt/net/voip" path="frameworks/opt/net/voip" revision="0f722c7f09ce67e058eb1cfaabf1d85f1abdf797" />
+  <project name="platform/frameworks/opt/photoviewer" path="frameworks/opt/photoviewer" revision="8c32972911bf73babdb01d30267f57255e242d78" />
+  <project groups="pdk" name="platform/frameworks/opt/telephony" path="frameworks/opt/telephony" revision="93faaed9056491c551ef7046e9e1de7d6397e95c" />
+  <project name="platform/frameworks/opt/timezonepicker" path="frameworks/opt/timezonepicker" revision="3820b87bfbc86d066e9093e78254e1f3728ad77d" />
+  <project name="platform/frameworks/opt/vcard" path="frameworks/opt/vcard" revision="5907243e6cf0603adf266ebfa7ee5ee465b9c596" />
+  <project name="platform/frameworks/opt/widget" path="frameworks/opt/widget" revision="466e0e0307b3f6aa4f4be3d9419b5996bd389da5" />
+  <project groups="pdk" name="platform/frameworks/rs" path="frameworks/rs" revision="ad0544fdf918e64cec05d1c98588880f10b09220" />
+  <project name="platform/frameworks/support" path="frameworks/support" revision="f05c07d3528765076adc16337a1f68f1700955dc" />
+  <project name="platform/frameworks/testing" path="frameworks/testing" revision="5c8e0271db889518f5969b142a37faa01a4ee54d" />
+  <project name="platform/frameworks/volley" path="frameworks/volley" revision="0e406003b5d434d8f16d7d6ad97d446060b788e6" />
+  <project name="platform/frameworks/webview" path="frameworks/webview" revision="6ed700e171cb2ee3303c08a1db2abc0e56fd307a" />
+  <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="a62c3572e60ae0446632de15418a65089cccf551" />
+  <project name="platform/hardware/akm" path="hardware/akm" revision="32838ef838d1341aa8b77022869b801fb0bbb26c" />
+  <project groups="pdk" name="platform/hardware/broadcom/libbt" path="hardware/broadcom/libbt" revision="55ddd0cce019e88829f92b2fe4e17d5869daa9b9" />
+  <project groups="broadcom_wlan" name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="47a3b8f496e6d2a836ac6b7268e5626c969542ec" />
+  <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="0f5bc7cd710fac85377621a8b9a4c364af80605f" />
+  <project groups="pdk" name="platform/hardware/libhardware" path="hardware/libhardware" revision="3e618a6aa10c783d1536f20edfc3347939cfa18e" />
+  <project groups="pdk" name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="4c20a09e8684657448f0bc97a2da4e56c94d484e" />
+  <project groups="qcom" name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="d47ff224c7b24933c701acae8d5e4c98a1bc80af" />
+  <project groups="qcom" name="platform/hardware/qcom/bt" path="hardware/qcom/bt" revision="cf314a462ba06f4bd3352d5d4630edcf6edbbe97" />
+  <project groups="qcom" name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="fbf72e519ec5fe2f2720b1a3d119e2d69e172e34" />
+  <project groups="qcom" name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="0a611c6ae11b65fec5ada5ecaa0893541db34156" />
+  <project groups="qcom" name="platform/hardware/qcom/keymaster" path="hardware/qcom/keymaster" revision="70d36107318e1d3f7abf62a56279b3f9da3ff000" />
+  <project groups="qcom" name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="1208a868bcb0ffaa650a7e68b51031254c775d39" />
+  <project groups="qcom_msm8960" name="platform/hardware/qcom/msm8960" path="hardware/qcom/msm8960" revision="ca38ed098b05a79d20e852348f27d7c40a53f801" />
+  <project groups="qcom_msm8x74" name="platform/hardware/qcom/msm8x74" path="hardware/qcom/msm8x74" revision="0c6844ea9ee14fd7bbfd6af0bcc6b6b682f46d1c" />
+  <project groups="qcom" name="platform/hardware/qcom/power" path="hardware/qcom/power" revision="ff9f4538c09399030fa73e3e65a167852cb91e8f" />
+  <project groups="qcom" name="platform/hardware/qcom/sensors" path="hardware/qcom/sensors" revision="07c5bcdb36158e22d33bac02eecd83d4ff1fb2f8" />
+  <project groups="qcom_wlan" name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="daa321b0ad8c10b454dc28d7e6dadc72196a8c7a" />
+  <project groups="pdk" name="platform/hardware/ril" path="hardware/ril" revision="eb2a93458204a928edfe36f043ddb48cf5575143" />
+  <project groups="exynos5" name="platform/hardware/samsung_slsi/exynos5" path="hardware/samsung_slsi/exynos5" revision="d7bd354358ecfb1e52afb3da4fc586c0822c696a" />
+  <project name="platform/hardware/ti/omap3" path="hardware/ti/omap3" revision="949aad363a9cc794f9ac8fd42338ae1678e50bc1" />
+  <project groups="omap4" name="platform/hardware/ti/omap4xxx" path="hardware/ti/omap4xxx" revision="c32caab84ff9edc1489ed6c8079c7d252caafc4d" />
+  <project name="platform/libcore" path="libcore" revision="d343e35535a99bad32eea0defc8a3e9c23c9967f" />
+  <project groups="pdk-java" name="platform/libnativehelper" path="libnativehelper" revision="b37e11d07dec2d49b576709ae8e0568a9daabd07" />
+  <project name="platform/ndk" path="ndk" revision="f584f76882baf374166cf12b99cd5f3dbdf3b6b9" />
+  <project name="platform/packages/apps/BasicSmsReceiver" path="packages/apps/BasicSmsReceiver" revision="80327793c4b4ebf4a6a53b72e46c477afe18f135" />
+  <project name="platform/packages/apps/Bluetooth" path="packages/apps/Bluetooth" revision="7efa9db2129c99475684a2e44c4fb89cce3134bc" />
+  <project name="platform/packages/apps/Browser" path="packages/apps/Browser" revision="fe4083510dc773911651456f150bf5432f81a6c0" />
+  <project name="platform/packages/apps/Calculator" path="packages/apps/Calculator" revision="6c7521bb685c9b7b7c36f2077612d4b1a0e808d4" />
+  <project name="platform/packages/apps/Calendar" path="packages/apps/Calendar" revision="2d72f6bed6a0eeaddbda08393063fe873c1c7922" />
+  <project name="platform/packages/apps/Camera" path="packages/apps/Camera" revision="b0e357d548fb8d10896200add2b932199a96a2ea" />
+  <project name="platform/packages/apps/Camera2" path="packages/apps/Camera2" revision="ece4866dc575b956801f6dab2d6c4923e272c5fa" />
+  <project name="platform/packages/apps/CellBroadcastReceiver" path="packages/apps/CellBroadcastReceiver" revision="21d8baf492007cc01545905de33ecefe5d947843" />
+  <project name="platform/packages/apps/CertInstaller" path="packages/apps/CertInstaller" revision="483a188feda6e9d311aef437d28f30e1fb6afeb0" />
+  <project name="platform/packages/apps/Contacts" path="packages/apps/Contacts" revision="24a4f48dc5c768188143648e267889477e4185e8" />
+  <project name="platform/packages/apps/ContactsCommon" path="packages/apps/ContactsCommon" revision="6ce4a3bc083a7dbcc7ffa2bebff242638d7f8e61" />
+  <project name="platform/packages/apps/DeskClock" path="packages/apps/DeskClock" revision="d3bfe9223f3e70271813f48b8ef5500c3a90c0b3" />
+  <project name="platform/packages/apps/Dialer" path="packages/apps/Dialer" revision="5cb300ef50e9942eef746319dd1b1b6e7c2c05e2" />
+  <project name="platform/packages/apps/Email" path="packages/apps/Email" revision="22766dcf6a44416b2972c053739472317017257d" />
+  <project name="platform/packages/apps/Exchange" path="packages/apps/Exchange" revision="ab03a7f9b197b6ffcc390dd5fb589067a5161148" />
+  <project name="platform/packages/apps/Gallery" path="packages/apps/Gallery" revision="9595006a3347c08e6b8e31d679903bb8f77a343d" />
+  <project name="platform/packages/apps/Gallery2" path="packages/apps/Gallery2" revision="9cde04ed08f3a5201a007d78b3c89f43fb3003e0" />
+  <project name="platform/packages/apps/HTMLViewer" path="packages/apps/HTMLViewer" revision="7498890092c388dc59ca932e09ec79dd568b1a19" />
+  <project name="platform/packages/apps/InCallUI" path="packages/apps/InCallUI" revision="d968d1a28dae45229b1be9f05bef8df13821e94d" />
+  <project name="platform/packages/apps/KeyChain" path="packages/apps/KeyChain" revision="e6243f79f3ce6daeb2d8d879e6e1a684ffc1b2fc" />
+  <project name="platform/packages/apps/Launcher2" path="packages/apps/Launcher2" revision="31569f6dbd44d443ff54c460b733e62fc37d2319" />
+  <project name="platform/packages/apps/Launcher3" path="packages/apps/Launcher3" revision="3a9f3a7806a0153865415d6207c6812915d3f6b1" />
+  <project name="platform/packages/apps/LegacyCamera" path="packages/apps/LegacyCamera" revision="d9b5d8941d1ec47ff391da2b8cc8ec90f902062f" />
+  <project name="platform/packages/apps/Mms" path="packages/apps/Mms" revision="e770738ea4389afddb0b4e6c69749f9456ed0f48" />
+  <project name="platform/packages/apps/Music" path="packages/apps/Music" revision="bfca689bb6605cfcd1e0c1781c707735efb7444e" />
+  <project name="platform/packages/apps/MusicFX" path="packages/apps/MusicFX" revision="aaa2f99caac6f088b23de55fe2eb1e8ee305b1fb" />
+  <project name="platform/packages/apps/Nfc" path="packages/apps/Nfc" revision="f62a9a00a13ba333e88cb9e8ce2553d6acf708ad" />
+  <project name="platform/packages/apps/OneTimeInitializer" path="packages/apps/OneTimeInitializer" revision="01e429c08e51291315890de9677151a7e0b6ad35" />
+  <project name="platform/packages/apps/PackageInstaller" path="packages/apps/PackageInstaller" revision="212398024b4491276ef00cf7fcd829c89200b6ba" />
+  <project name="platform/packages/apps/Phone" path="packages/apps/Phone" revision="bf4ec5b1258628bfa6a82aa0d80f348a77bbf194" />
+  <project name="platform/packages/apps/PhoneCommon" path="packages/apps/PhoneCommon" revision="16f62c5ab5c21981e63d678187ad4b44e686332b" />
+  <project name="platform/packages/apps/Protips" path="packages/apps/Protips" revision="325232e344b257a3c236ead2adc60c7378f226c0" />
+  <project name="platform/packages/apps/Provision" path="packages/apps/Provision" revision="78ca0db658fe6253d506916e36319e620476f809" />
+  <project name="platform/packages/apps/QuickSearchBox" path="packages/apps/QuickSearchBox" revision="cfb7af6652a7fbcc0f86341edfe14dc316c9ff37" />
+  <project name="platform/packages/apps/Settings" path="packages/apps/Settings" revision="2abbacb7d46657e5863eb2ef0035521ffc41a0a8" />
+  <project name="platform/packages/apps/SmartCardService" path="packages/apps/SmartCardService" revision="29eae320a4bd222b5ff1c092f84f1aebba88d0b7" />
+  <project name="platform/packages/apps/SoundRecorder" path="packages/apps/SoundRecorder" revision="b0e671faf142fa0b933b4f1cd7d186b1f37ebe46" />
+  <project name="platform/packages/apps/SpareParts" path="packages/apps/SpareParts" revision="4db997871e3f4c3f84660815096e5276b47c5c91" />
+  <project name="platform/packages/apps/SpeechRecorder" path="packages/apps/SpeechRecorder" revision="536aa74ff3a77186bef29dc9333a34688fa59d13" />
+  <project name="platform/packages/apps/Stk" path="packages/apps/Stk" revision="115b75461f8e1fb432fe1a892549ca1c96cef497" />
+  <project name="platform/packages/apps/Tag" path="packages/apps/Tag" revision="f830b07335bd2dd794b84507b5390f7d893fe428" />
+  <project name="platform/packages/apps/TvSettings" path="packages/apps/TvSettings" revision="24e45eaf3b4badaf02e449e7f6d07c72e743f521" />
+  <project name="platform/packages/apps/UnifiedEmail" path="packages/apps/UnifiedEmail" revision="d4537c907920f4470b70e91c187ef7a0b31632db" />
+  <project name="platform/packages/apps/VideoEditor" path="packages/apps/VideoEditor" revision="a49ea28e1628f507ae3a564215664c29c5fa1215" />
+  <project name="platform/packages/apps/VoiceDialer" path="packages/apps/VoiceDialer" revision="72df4532dfca9a82e8aef55fcdfce3026d3d3312" />
+  <project name="platform/packages/experimental" path="packages/experimental" revision="588c7cda9c62fb77d23bc089a63cba8a96bc9ffb" />
+  <project name="platform/packages/inputmethods/LatinIME" path="packages/inputmethods/LatinIME" revision="159474f2ae5d13308ca1b92b8a5ccd809ec6a450" />
+  <project name="platform/packages/inputmethods/OpenWnn" path="packages/inputmethods/OpenWnn" revision="59aefa242169b7a51c2381daee58ff22fd1834ce" />
+  <project name="platform/packages/inputmethods/PinyinIME" path="packages/inputmethods/PinyinIME" revision="49aebad1c1cfbbcaa9288ffed5161e79e57c3679" />
+  <project name="platform/packages/providers/ApplicationsProvider" path="packages/providers/ApplicationsProvider" revision="3347f31bd268ca3153abe5def9361f625bd73efd" />
+  <project name="platform/packages/providers/CalendarProvider" path="packages/providers/CalendarProvider" revision="20360f2fdd7ad2de1234b7ed61e3ea120f0dc635" />
+  <project name="platform/packages/providers/ContactsProvider" path="packages/providers/ContactsProvider" revision="6ac2395324c0e7539434b7c68ec738f867d7ed37" />
+  <project name="platform/packages/providers/DownloadProvider" path="packages/providers/DownloadProvider" revision="90e7485d68095b5fc5044dd1bc6cd4dfc485eaa3" />
+  <project name="platform/packages/providers/MediaProvider" path="packages/providers/MediaProvider" revision="501b93fb00db86fe4fb53dc000f6f11587afe4b0" />
+  <project name="platform/packages/providers/PartnerBookmarksProvider" path="packages/providers/PartnerBookmarksProvider" revision="96d0a80af45923767baf449fc8c735c2f71d64ae" />
+  <project name="platform/packages/providers/TelephonyProvider" path="packages/providers/TelephonyProvider" revision="91e705bc7662192ea33f2bac6b0a6c79fc9bc7ab" />
+  <project name="platform/packages/providers/UserDictionaryProvider" path="packages/providers/UserDictionaryProvider" revision="361f35b7b1fe758d93e0952536a298b2ed045a89" />
+  <project name="platform/packages/screensavers/Basic" path="packages/screensavers/Basic" revision="4b5d9d8bea733c4e5876541831f27bf40588b516" />
+  <project name="platform/packages/screensavers/PhotoTable" path="packages/screensavers/PhotoTable" revision="a5e0fee8e923cfc8682eb4431bc3997ed15f649a" />
+  <project name="platform/packages/screensavers/WebView" path="packages/screensavers/WebView" revision="6e0a80f6faed6191acc8ce1b6c79eada09e9e042" />
+  <project name="platform/packages/services/Telephony" path="packages/services/Telephony" revision="aa156251eb0414b8c6546c98769789dc28b38140" />
+  <project name="platform/packages/wallpapers/Basic" path="packages/wallpapers/Basic" revision="2e1d8404b87caf13cde644959f28213f2db09843" />
+  <project name="platform/packages/wallpapers/Galaxy4" path="packages/wallpapers/Galaxy4" revision="34b31b45e75b2e73a770fef1a2f9a862b10f1a57" />
+  <project name="platform/packages/wallpapers/HoloSpiral" path="packages/wallpapers/HoloSpiral" revision="63b75996a7cfb713a6a6feb5c774ba4b46c7d6eb" />
+  <project name="platform/packages/wallpapers/LivePicker" path="packages/wallpapers/LivePicker" revision="8082f92e76774607d62412e8e1191dd940f055ba" />
+  <project name="platform/packages/wallpapers/MagicSmoke" path="packages/wallpapers/MagicSmoke" revision="f01ea4c07914010d52a42130acb7e67d4306fbda" />
+  <project name="platform/packages/wallpapers/MusicVisualization" path="packages/wallpapers/MusicVisualization" revision="72fbcf3a8e4ebee42c36a5887432ca823ef0e4e5" />
+  <project name="platform/packages/wallpapers/NoiseField" path="packages/wallpapers/NoiseField" revision="7d3e52a18a1255baffd7c0675a465f1b85b99f56" />
+  <project name="platform/packages/wallpapers/PhaseBeam" path="packages/wallpapers/PhaseBeam" revision="0da76f35378677f1102e0be218ce1993c0e528b6" />
+  <project groups="pdk" name="platform/pdk" path="pdk" revision="d440d4219412981df7ef90bed65acf29b2e7ea6a" />
+  <project name="platform/prebuilts/android-emulator" path="prebuilts/android-emulator" revision="d6a246c24accff42eb433f5e39d14cb24faf1e58" />
+  <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/3.1" path="prebuilts/clang/darwin-x86/3.1" revision="426233405bef3c7c825095ab14256c3773894b9b" />
+  <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/3.2" path="prebuilts/clang/darwin-x86/3.2" revision="af856d77b3cbb1f6afccdc531bee991403c28907" />
+  <project groups="darwin,arm" name="platform/prebuilts/clang/darwin-x86/arm/3.3" path="prebuilts/clang/darwin-x86/arm/3.3" revision="54acc51e28850485e380b55916868a4e1ff17998" />
+  <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/host/3.4" path="prebuilts/clang/darwin-x86/host/3.4" revision="a798fe00dbd92ad4e5f7123a2e2bc1d805db04f6" />
+  <project groups="pdk,darwin" name="platform/prebuilts/clang/darwin-x86/host/3.5" path="prebuilts/clang/darwin-x86/host/3.5" revision="ce812d27fb78972e71482e93241b9770ca54845d" />
+  <project groups="darwin,mips" name="platform/prebuilts/clang/darwin-x86/mips/3.3" path="prebuilts/clang/darwin-x86/mips/3.3" revision="da3dad928542362835082b2eda44e4dc315d65bb" />
+  <project groups="darwin,x86" name="platform/prebuilts/clang/darwin-x86/x86/3.3" path="prebuilts/clang/darwin-x86/x86/3.3" revision="f67a83f35e30f92b312fbee852184c3f6dc38f34" />
+  <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde" />
+  <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8" />
+  <project groups="linux,arm" name="platform/prebuilts/clang/linux-x86/arm/3.3" path="prebuilts/clang/linux-x86/arm/3.3" revision="2f6d2db9e2af3507d132cf5d286a42fe1d47f7bc" />
+  <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.4" path="prebuilts/clang/linux-x86/host/3.4" revision="fae26a039f79d780ddedcad07f164d9e6c05fc87" />
+  <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="485ffdc99707f81f4201e85bbbb937f23e1e04aa" />
+  <project groups="linux,mips" name="platform/prebuilts/clang/linux-x86/mips/3.3" path="prebuilts/clang/linux-x86/mips/3.3" revision="51f8e2760628588fe268438d612d942c30d13fb2" />
+  <project groups="linux,x86" name="platform/prebuilts/clang/linux-x86/x86/3.3" path="prebuilts/clang/linux-x86/x86/3.3" revision="017a8a67f92a66b29ab17772e50642a7b9d0f8e6" />
+  <project name="platform/prebuilts/devtools" path="prebuilts/devtools" revision="be724be535ea50585d8c625b768ccb63aacd2926" />
+  <project groups="pdk" name="platform/prebuilts/eclipse" path="prebuilts/eclipse" revision="cf9f78f8cf41b16edf9f712598a42743d5cea4af" />
+  <project groups="notdefault,eclipse" name="platform/prebuilts/eclipse-build-deps" path="prebuilts/eclipse-build-deps" revision="ceb739d6a7c10f5fb5a6cf6e1f702453b1361ad3" />
+  <project groups="notdefault,eclipse" name="platform/prebuilts/eclipse-build-deps-sources" path="prebuilts/eclipse-build-deps-sources" revision="8b7d8f6033ffe2d22905d10cf6d57d5bdcbe519b" />
+  <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.8" revision="a261d38eaebb7ff406a6bb60237b36fc61714d46" />
+  <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" path="prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9" revision="32d722d66d7a935a8b6f8e6ab2d5d8bf0e9e0986" />
+  <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8" revision="6d08ca9f45ff685648fd13c75bf5cac4b11c19bb" />
+  <project groups="pdk,darwin,arm" name="platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.8" revision="264394c23b2686ce52cd4ffb116ced127aa7f8fc" />
+  <project groups="pdk,darwin" name="platform/prebuilts/gcc/darwin-x86/host/headers" path="prebuilts/gcc/darwin-x86/host/headers" revision="4ac4f7cc41cf3c9e36fc3d6cf37fd1cfa9587a68" />
+  <project groups="pdk,darwin" name="platform/prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1" path="prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1" revision="8834958755acc291d126ba7ee38ac731d04f9c9e" />
+  <project groups="pdk,darwin,mips" name="platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.8" path="prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.8" revision="3b5bef47de8017ff39ef5bfbe801e3fa6b272fab" />
+  <project name="platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" path="prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9" revision="367a6529b0cc9f5ac5ca69226f583420563fd473" />
+  <project groups="pdk,darwin,mips" name="platform/prebuilts/gcc/darwin-x86/mips/mipsel-linux-android-4.8" path="prebuilts/gcc/darwin-x86/mips/mipsel-linux-android-4.8" revision="ba97180acd4251d3acf08530faa4a724af74abd3" />
+  <project groups="pdk,darwin,x86" name="platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.8" revision="c3c37a54f07d51a50e17d63dbf1d92da343f45ce" />
+  <project name="platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9" revision="a7c5a1df753fd3a24494d5e1fe00211048be5c1d" />
+  <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="7334f0a7a872700d0aaf00bea75917c077c45530" />
+  <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9" revision="a3f0180676c6b6cd9c664704f86855d3404ae4dd" />
+  <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="26e93f6af47f7bd3a9beb5c102a5f45e19bfa38a" />
+  <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="d9735fc81434f2af2c44d86ca57740c673c8d9bc" />
+  <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="eb5c9f0ae36bf964f6855bde54e1b387e2c26bb6" />
+  <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="1b0544da652fda90a41a1f69889d6b137ce20fb9" />
+  <project name="platform/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" revision="2725a175a32032fb9a63e247c176ecc3d448ea27" />
+  <project groups="pdk,linux,mips" name="platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.8" path="prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.8" revision="38586de6b44714b4adcf21119fe6b267e33f3ca6" />
+  <project name="platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" path="prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9" revision="eabc7ae8ed527ee3d4517196732fa3f3e8939a28" />
+  <project groups="pdk,linux,mips" name="platform/prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.8" path="prebuilts/gcc/linux-x86/mips/mipsel-linux-android-4.8" revision="c06b9b305c365163c99d4ffba49ac37ce2716024" />
+  <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="e08fa7e57a573a9baa5ccd8d4b8d73cc871f9b48" />
+  <project name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9" revision="e99278016e6285363bc20d1b35d4b9b5c4e8b0a0" />
+  <project name="platform/prebuilts/gradle-plugin" path="prebuilts/gradle-plugin" revision="e7814a3cbb96742ff74505a1fc152cb534fbf2f9" />
+  <project name="platform/prebuilts/maven_repo/android" path="prebuilts/maven_repo/android" revision="0dbe3df0f057de9e83e599b9be2ca866c673130d" />
+  <project groups="pdk" name="platform/prebuilts/misc" path="prebuilts/misc" revision="3cc2e316acf9da501479bbfd85159407239994d2" />
+  <project groups="pdk" name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="7a8bc5c36d519c41de61765ff94245f56c4bed7a" />
+  <project groups="darwin" name="platform/prebuilts/python/darwin-x86/2.7.5" path="prebuilts/python/darwin-x86/2.7.5" revision="2bdd4fd418614c7c0101147d02199d0e47c4980e" />
+  <project groups="linux" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="6fbc8802b3b68d24a4ee83f164b22490cf702ff2" />
+  <project groups="pdk" name="platform/prebuilts/qemu-kernel" path="prebuilts/qemu-kernel" revision="5f91f38eac40a8465f3a7e4aa298a75afcf2936a" />
+  <project name="platform/prebuilts/runtime" path="prebuilts/runtime" revision="56e663b8ec9cd0df9ce5afdc7b7d56460faf44c8" />
+  <project groups="pdk" name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="52043ca65e06bc84779dd8d3e55e72ad04bcef59" />
+  <project groups="pdk,tools" name="platform/prebuilts/tools" path="prebuilts/tools" revision="130c3d0a1a484d617531d75ddd50714f68213cbb" />
+  <project name="platform/sdk" path="sdk" revision="1af9ef83f5f6c6fd9202d5bdd8d4248a4eb855aa" />
+  <project groups="pdk" name="platform/system/core" path="system/core" revision="cddc97cb3a927d179a42e0fec77f0d267fcd74d1" />
+  <project groups="pdk" name="platform/system/extras" path="system/extras" revision="97ed949ec7bef088ca3d06fb7b5f3bdad9a5103c" />
+  <project name="platform/system/keymaster" path="system/keymaster" revision="7a70abbf29293b30bb1e7ed3a58deb40f8774a53" />
+  <project groups="pdk" name="platform/system/media" path="system/media" revision="77f0f32b32adc5ba1134e7a68e4d907c4f695eb6" />
+  <project groups="pdk" name="platform/system/netd" path="system/netd" revision="f5d949ef0991737af9daa7ba702cc2ec638e435b" />
+  <project groups="pdk" name="platform/system/security" path="system/security" revision="0387a7fd23021b904612101b727a2060847f6169" />
+  <project groups="pdk" name="platform/system/vold" path="system/vold" revision="c0c2867518eed4539444434c95fad8185a6ac08e" />
+  <project groups="notdefault,tools" name="platform/tools/adt/eclipse" path="tools/adt/eclipse" revision="ede2ed86419bb4c78428f1ac09825b1a247d8e24" />
+  <project groups="notdefault,tools" name="platform/tools/adt/idea" path="tools/adt/idea" revision="50a5da1af3e851df7aff37c291541000685bcad4" />
+  <project groups="notdefault,tools" name="platform/tools/base" path="tools/base" revision="4dc06057ba77596807e2d28c715719f240f71549" />
+  <project groups="notdefault,tools" name="platform/tools/build" path="tools/build" revision="69c4b95102b4b9862bfba68b3eaf5b7537a705ee" />
+  <project groups="notdefault,tools" name="platform/tools/emulator" path="tools/emulator" revision="c427e5d5227ba9413307670a5d758d9ced394a7e" />
+  <project groups="tools" name="platform/tools/external/fat32lib" path="tools/external/fat32lib" revision="3880776e41ff7def06e351720f2d162f88b58a03" />
+  <project groups="tools" name="platform/tools/external/gradle" path="tools/external/gradle" revision="842b7a27df8606faa29b0875a13270701eb78dd8" />
+  <project groups="notdefault,tools" name="platform/tools/idea" path="tools/idea" revision="12356153d01fcde14dd3a06948cfded92c20d068" />
+  <project groups="notdefault,motodev" name="platform/tools/motodev" path="tools/motodev" revision="69989786cefbde82527960a1e100ec9afba46a98" />
+  <project groups="notdefault,tools" name="platform/tools/studio/cloud" path="tools/studio/cloud" revision="839eb097c5fc73f91a722f1457a2e8e11eb4e1a5" />
+  <project groups="notdefault,tools" name="platform/tools/swt" path="tools/swt" revision="aaf3131b0e4b15d39156a6e94e5da06b0183d61d" />
+</manifest>
diff --git a/buildbot/buildbot_run.py b/buildbot/buildbot_run.py
index b20a424..6382707 100755
--- a/buildbot/buildbot_run.py
+++ b/buildbot/buildbot_run.py
@@ -7,6 +7,7 @@
 """Argument-less script to select what to run on the buildbots."""
 
 
+import filecmp
 import os
 import shutil
 import subprocess
@@ -30,7 +31,8 @@
 
 def CallSubProcess(*args, **kwargs):
   """Wrapper around subprocess.call which treats errors as build exceptions."""
-  retcode = subprocess.call(*args, **kwargs)
+  with open(os.devnull) as devnull_fd:
+    retcode = subprocess.call(stdin=devnull_fd, *args, **kwargs)
   if retcode != 0:
     print '@@@STEP_EXCEPTION@@@'
     sys.exit(1)
@@ -49,10 +51,6 @@
 
   print '@@@BUILD_STEP Initialize CMake checkout@@@'
   os.mkdir(CMAKE_DIR)
-  CallSubProcess(['git', 'config', '--global', 'user.name', 'trybot'])
-  CallSubProcess(['git', 'config', '--global',
-                  'user.email', 'chrome-bot@google.com'])
-  CallSubProcess(['git', 'config', '--global', 'color.ui', 'false'])
 
   print '@@@BUILD_STEP Sync CMake@@@'
   CallSubProcess(
@@ -82,27 +80,44 @@
     print '@@@BUILD_STEP Clobber Android checkout@@@'
     shutil.rmtree(ANDROID_DIR)
 
-  # The release of Android we use is static, so there's no need to do anything
-  # if the directory already exists.
-  if os.path.isdir(ANDROID_DIR):
+  # (Re)create the directory so that the following steps will succeed.
+  if not os.path.isdir(ANDROID_DIR):
+    os.mkdir(ANDROID_DIR)
+
+  # We use a manifest from the gyp project listing pinned revisions of AOSP to
+  # use, to ensure that we test against a stable target. This needs to be
+  # updated to pick up new build system changes sometimes, so we must test if
+  # it has changed.
+  manifest_filename = 'aosp_manifest.xml'
+  gyp_manifest = os.path.join(BUILDBOT_DIR, manifest_filename)
+  android_manifest = os.path.join(ANDROID_DIR, '.repo', 'manifests',
+                                  manifest_filename)
+  manifest_is_current = (os.path.isfile(android_manifest) and
+                         filecmp.cmp(gyp_manifest, android_manifest))
+  if not manifest_is_current:
+    # It's safe to repeat these steps, so just do them again to make sure we are
+    # in a good state.
+    print '@@@BUILD_STEP Initialize Android checkout@@@'
+    CallSubProcess(
+        ['repo', 'init',
+         '-u', 'https://android.googlesource.com/platform/manifest',
+         '-b', 'master',
+         '-g', 'all,-notdefault,-device,-darwin,-mips,-x86'],
+        cwd=ANDROID_DIR)
+    shutil.copy(gyp_manifest, android_manifest)
+
+    print '@@@BUILD_STEP Sync Android@@@'
+    CallSubProcess(['repo', 'sync', '-j4', '-m', manifest_filename],
+                   cwd=ANDROID_DIR)
+
+  # If we already built the system image successfully and didn't sync to a new
+  # version of the source, skip running the build again as it's expensive even
+  # when there's nothing to do.
+  system_img = os.path.join(ANDROID_DIR, 'out', 'target', 'product', 'generic',
+                            'system.img')
+  if manifest_is_current and os.path.isfile(system_img):
     return
 
-  print '@@@BUILD_STEP Initialize Android checkout@@@'
-  os.mkdir(ANDROID_DIR)
-  CallSubProcess(['git', 'config', '--global', 'user.name', 'trybot'])
-  CallSubProcess(['git', 'config', '--global',
-                  'user.email', 'chrome-bot@google.com'])
-  CallSubProcess(['git', 'config', '--global', 'color.ui', 'false'])
-  CallSubProcess(
-      ['repo', 'init',
-       '-u', 'https://android.googlesource.com/platform/manifest',
-       '-b', 'android-4.2.1_r1',
-       '-g', 'all,-notdefault,-device,-darwin,-mips,-x86'],
-      cwd=ANDROID_DIR)
-
-  print '@@@BUILD_STEP Sync Android@@@'
-  CallSubProcess(['repo', 'sync', '-j4'], cwd=ANDROID_DIR)
-
   print '@@@BUILD_STEP Build Android@@@'
   CallSubProcess(
       ['/bin/bash',
@@ -113,14 +128,28 @@
 def StartAndroidEmulator():
   """Start an android emulator from the built android tree."""
   print '@@@BUILD_STEP Start Android emulator@@@'
-  android_host_bin = '$ANDROID_HOST_OUT/bin'
+
+  CallSubProcess(['/bin/bash', '-c',
+      '%s && adb kill-server ' % _ANDROID_SETUP],
+      cwd=ANDROID_DIR)
+
+  # If taskset is available, use it to force adbd to run only on one core, as,
+  # sadly, it improves its reliability (see crbug.com/268450).
+  adbd_wrapper = ''
+  with open(os.devnull, 'w') as devnull_fd:
+    if subprocess.call(['which', 'taskset'], stdout=devnull_fd) == 0:
+      adbd_wrapper = 'taskset -c 0'
+  CallSubProcess(['/bin/bash', '-c',
+      '%s && %s adb start-server ' % (_ANDROID_SETUP, adbd_wrapper)],
+      cwd=ANDROID_DIR)
+
   subprocess.Popen(
       ['/bin/bash', '-c',
-       '%s && %s/emulator -no-window' % (_ANDROID_SETUP, android_host_bin)],
+       '%s && emulator -no-window' % _ANDROID_SETUP],
       cwd=ANDROID_DIR)
   CallSubProcess(
       ['/bin/bash', '-c',
-       '%s && %s/adb wait-for-device' % (_ANDROID_SETUP, android_host_bin)],
+       '%s && adb wait-for-device' % _ANDROID_SETUP],
       cwd=ANDROID_DIR)
 
 
diff --git a/pylib/gyp/__init__.py b/pylib/gyp/__init__.py
index 30edea5..1cd57b0 100755
--- a/pylib/gyp/__init__.py
+++ b/pylib/gyp/__init__.py
@@ -49,7 +49,7 @@
 
 def Load(build_files, format, default_variables={},
          includes=[], depth='.', params=None, check=False,
-         circular_check=True):
+         circular_check=True, duplicate_basename_check=True):
   """
   Loads one or more specified build files.
   default_variables and includes will be copied before use.
@@ -126,6 +126,7 @@
   # Process the input specific to this generator.
   result = gyp.input.Load(build_files, default_variables, includes[:],
                           depth, generator_input_info, check, circular_check,
+                          duplicate_basename_check,
                           params['parallel'], params['root_targets'])
   return [generator] + result
 
@@ -324,6 +325,16 @@
   parser.add_option('--no-circular-check', dest='circular_check',
                     action='store_false', default=True, regenerate=False,
                     help="don't check for circular relationships between files")
+  # --no-duplicate-basename-check disables the check for duplicate basenames
+  # in a static_library/shared_library project. Visual C++ 2008 generator
+  # doesn't support this configuration. Libtool on Mac also generates warnings
+  # when duplicate basenames are passed into Make generator on Mac.
+  # TODO(yukawa): Remove this option when these legacy generators are
+  # deprecated.
+  parser.add_option('--no-duplicate-basename-check',
+                    dest='duplicate_basename_check', action='store_false',
+                    default=True, regenerate=False,
+                    help="don't check for duplicate basenames")
   parser.add_option('--no-parallel', action='store_true', default=False,
                     help='Disable multiprocessing')
   parser.add_option('-S', '--suffix', dest='suffix', default='',
@@ -496,11 +507,10 @@
               'root_targets': options.root_targets}
 
     # Start with the default variables from the command line.
-    [generator, flat_list, targets, data] = Load(build_files, format,
-                                                 cmdline_default_variables,
-                                                 includes, options.depth,
-                                                 params, options.check,
-                                                 options.circular_check)
+    [generator, flat_list, targets, data] = Load(
+        build_files, format, cmdline_default_variables, includes, options.depth,
+        params, options.check, options.circular_check,
+        options.duplicate_basename_check)
 
     # TODO(mark): Pass |data| for now because the generator needs a list of
     # build files that came in.  In the future, maybe it should just accept
diff --git a/pylib/gyp/generator/analyzer.py b/pylib/gyp/generator/analyzer.py
index 007d17d..9c2ef9f 100644
--- a/pylib/gyp/generator/analyzer.py
+++ b/pylib/gyp/generator/analyzer.py
@@ -4,15 +4,55 @@
 
 """
 This script is intended for use as a GYP_GENERATOR. It takes as input (by way of
-the generator flag file_path) the list of relative file paths to consider. If
-any target has at least one of the paths as a source (or input to an action or
-rule) then 'Found dependency' is output, otherwise 'No dependencies' is output.
+the generator flag config_path) the path of a json file that dictates the files
+and targets to search for. The following keys are supported:
+files: list of paths (relative) of the files to search for.
+targets: list of targets to search for. The target names are unqualified.
+
+The following is output:
+error: only supplied if there is an error.
+warning: only supplied if there is a warning.
+targets: the set of targets passed in via targets that either directly or
+  indirectly depend upon the set of paths supplied in files.
+build_targets: minimal set of targets that directly depend on the changed
+  files and need to be built. The expectation is this set of targets is passed
+  into a build step.
+status: outputs one of three values: none of the supplied files were found,
+  one of the include files changed so that it should be assumed everything
+  changed (in this case targets and build_targets are not output) or at
+  least one file was found.
+
+If the generator flag analyzer_output_path is specified, output is written
+there. Otherwise output is written to stdout.
 """
 
 import gyp.common
 import gyp.ninja_syntax as ninja_syntax
+import json
 import os
 import posixpath
+import sys
+
+debug = False
+
+found_dependency_string = 'Found dependency'
+no_dependency_string = 'No dependencies'
+# Status when it should be assumed that everything has changed.
+all_changed_string = 'Found dependency (all)'
+
+# MatchStatus is used indicate if and how a target depends upon the supplied
+# sources.
+# The target's sources contain one of the supplied paths.
+MATCH_STATUS_MATCHES = 1
+# The target has a dependency on another target that contains one of the
+# supplied paths.
+MATCH_STATUS_MATCHES_BY_DEPENDENCY = 2
+# The target's sources weren't in the supplied paths and none of the target's
+# dependencies depend upon a target that matched.
+MATCH_STATUS_DOESNT_MATCH = 3
+# The target doesn't contain the source, but the dependent targets have not yet
+# been visited to determine a more specific status yet.
+MATCH_STATUS_TBD = 4
 
 generator_supports_multiple_toolsets = True
 
@@ -32,28 +72,33 @@
                'CONFIGURATION_NAME']:
   generator_default_variables[unused] = ''
 
-def __MakeRelativeTargetName(path):
-  """Converts a gyp target name into a relative name. For example, the path to a
-  gyp file may be something like c:\foo\bar.gyp:target, this converts it to
-  bar.gyp.
-  """
-  prune_path = os.getcwd()
-  if path.startswith(prune_path):
-    path = path[len(prune_path):]
-  # Gyp paths are always posix style.
-  path = path.replace('\\', '/')
-  if path.endswith('#target'):
-    path = path[0:len(path) - len('#target')]
+
+def _ToGypPath(path):
+  """Converts a path to the format used by gyp."""
+  if os.sep == '\\' and os.altsep == '/':
+    return path.replace('\\', '/')
   return path
 
-def __ExtractBasePath(target):
-  """Extracts the path components of the specified gyp target path."""
-  last_index = target.rfind('/')
-  if last_index == -1:
-    return ''
-  return target[0:(last_index + 1)]
 
-def __AddSources(sources, base_path, base_path_components, result):
+def _ResolveParent(path, base_path_components):
+  """Resolves |path|, which starts with at least one '../'. Returns an empty
+  string if the path shouldn't be considered. See _AddSources() for a
+  description of |base_path_components|."""
+  depth = 0
+  while path.startswith('../'):
+    depth += 1
+    path = path[3:]
+  # Relative includes may go outside the source tree. For example, an action may
+  # have inputs in /usr/include, which are not in the source tree.
+  if depth > len(base_path_components):
+    return ''
+  if depth == len(base_path_components):
+    return path
+  return '/'.join(base_path_components[0:len(base_path_components) - depth]) + \
+      '/' + path
+
+
+def _AddSources(sources, base_path, base_path_components, result):
   """Extracts valid sources from |sources| and adds them to |result|. Each
   source file is relative to |base_path|, but may contain '..'. To make
   resolving '..' easier |base_path_components| contains each of the
@@ -65,99 +110,380 @@
     if not len(source) or source.startswith('!!!') or source.startswith('$'):
       continue
     # variable expansion may lead to //.
+    org_source = source
     source = source[0] + source[1:].replace('//', '/')
     if source.startswith('../'):
-      path_components = base_path_components[:]
-      # Resolve relative paths.
-      while source.startswith('../'):
-        path_components.pop(len(path_components) - 1)
-        source = source[3:]
-      result.append('/'.join(path_components) + source)
+      source = _ResolveParent(source, base_path_components)
+      if len(source):
+        result.append(source)
       continue
     result.append(base_path + source)
+    if debug:
+      print 'AddSource', org_source, result[len(result) - 1]
 
-def __ExtractSourcesFromAction(action, base_path, base_path_components,
-                               results):
+
+def _ExtractSourcesFromAction(action, base_path, base_path_components,
+                              results):
   if 'inputs' in action:
-    __AddSources(action['inputs'], base_path, base_path_components, results)
+    _AddSources(action['inputs'], base_path, base_path_components, results)
 
-def __ExtractSources(target, target_dict):
-  base_path = posixpath.dirname(target)
+
+def _ToLocalPath(toplevel_dir, path):
+  """Converts |path| to a path relative to |toplevel_dir|."""
+  if path == toplevel_dir:
+    return ''
+  if path.startswith(toplevel_dir + '/'):
+    return path[len(toplevel_dir) + len('/'):]
+  return path
+
+
+def _ExtractSources(target, target_dict, toplevel_dir):
+  # |target| is either absolute or relative and in the format of the OS. Gyp
+  # source paths are always posix. Convert |target| to a posix path relative to
+  # |toplevel_dir_|. This is done to make it easy to build source paths.
+  base_path = posixpath.dirname(_ToLocalPath(toplevel_dir, _ToGypPath(target)))
   base_path_components = base_path.split('/')
-  # Add a trailing '/' so that __AddSources() can easily build paths.
+
+  # Add a trailing '/' so that _AddSources() can easily build paths.
   if len(base_path):
     base_path += '/'
+
+  if debug:
+    print 'ExtractSources', target, base_path
+
   results = []
   if 'sources' in target_dict:
-    __AddSources(target_dict['sources'], base_path, base_path_components,
-                 results)
-  # Include the inputs from any actions. Any changes to these effect the
+    _AddSources(target_dict['sources'], base_path, base_path_components,
+                results)
+  # Include the inputs from any actions. Any changes to these affect the
   # resulting output.
   if 'actions' in target_dict:
     for action in target_dict['actions']:
-      __ExtractSourcesFromAction(action, base_path, base_path_components,
-                                 results)
+      _ExtractSourcesFromAction(action, base_path, base_path_components,
+                                results)
   if 'rules' in target_dict:
     for rule in target_dict['rules']:
-      __ExtractSourcesFromAction(rule, base_path, base_path_components, results)
+      _ExtractSourcesFromAction(rule, base_path, base_path_components, results)
 
   return results
 
+
 class Target(object):
   """Holds information about a particular target:
-  sources: set of source files defined by this target. This includes inputs to
-           actions and rules.
-  deps: list of direct dependencies."""
-  def __init__(self):
-    self.sources = []
-    self.deps = []
+  deps: set of Targets this Target depends upon. This is not recursive, only the
+    direct dependent Targets.
+  match_status: one of the MatchStatus values.
+  back_deps: set of Targets that have a dependency on this Target.
+  visited: used during iteration to indicate whether we've visited this target.
+    This is used for two iterations, once in building the set of Targets and
+    again in _GetBuildTargets().
+  name: fully qualified name of the target.
+  requires_build: True if the target type is such that it needs to be built.
+    See _DoesTargetTypeRequireBuild for details.
+  added_to_compile_targets: used when determining if the target was added to the
+    set of targets that needs to be built.
+  in_roots: true if this target is a descendant of one of the root nodes.
+  is_executable: true if the type of target is executable."""
+  def __init__(self, name):
+    self.deps = set()
+    self.match_status = MATCH_STATUS_TBD
+    self.back_deps = set()
+    self.name = name
+    # TODO(sky): I don't like hanging this off Target. This state is specific
+    # to certain functions and should be isolated there.
+    self.visited = False
+    self.requires_build = False
+    self.added_to_compile_targets = False
+    self.in_roots = False
+    self.is_executable = False
 
-def __GenerateTargets(target_list, target_dicts):
-  """Generates a dictionary with the key the name of a target and the value a
-  Target."""
+
+class Config(object):
+  """Details what we're looking for
+  files: set of files to search for
+  targets: see file description for details."""
+  def __init__(self):
+    self.files = []
+    self.targets = set()
+
+  def Init(self, params):
+    """Initializes Config. This is a separate method as it raises an exception
+    if there is a parse error."""
+    generator_flags = params.get('generator_flags', {})
+    config_path = generator_flags.get('config_path', None)
+    if not config_path:
+      return
+    try:
+      f = open(config_path, 'r')
+      config = json.load(f)
+      f.close()
+    except IOError:
+      raise Exception('Unable to open file ' + config_path)
+    except ValueError as e:
+      raise Exception('Unable to parse config file ' + config_path + str(e))
+    if not isinstance(config, dict):
+      raise Exception('config_path must be a JSON file containing a dictionary')
+    self.files = config.get('files', [])
+    self.targets = set(config.get('targets', []))
+
+
+def _WasBuildFileModified(build_file, data, files, toplevel_dir):
+  """Returns true if the build file |build_file| is either in |files| or
+  one of the files included by |build_file| is in |files|. |toplevel_dir| is
+  the root of the source tree."""
+  if _ToLocalPath(toplevel_dir, _ToGypPath(build_file)) in files:
+    if debug:
+      print 'gyp file modified', build_file
+    return True
+
+  # First element of included_files is the file itself.
+  if len(data[build_file]['included_files']) <= 1:
+    return False
+
+  for include_file in data[build_file]['included_files'][1:]:
+    # |included_files| are relative to the directory of the |build_file|.
+    rel_include_file = \
+        _ToGypPath(gyp.common.UnrelativePath(include_file, build_file))
+    if _ToLocalPath(toplevel_dir, rel_include_file) in files:
+      if debug:
+        print 'included gyp file modified, gyp_file=', build_file, \
+            'included file=', rel_include_file
+      return True
+  return False
+
+
+def _GetOrCreateTargetByName(targets, target_name):
+  """Creates or returns the Target at targets[target_name]. If there is no
+  Target for |target_name| one is created. Returns a tuple of whether a new
+  Target was created and the Target."""
+  if target_name in targets:
+    return False, targets[target_name]
+  target = Target(target_name)
+  targets[target_name] = target
+  return True, target
+
+
+def _DoesTargetTypeRequireBuild(target_dict):
+  """Returns true if the target type is such that it needs to be built."""
+  # If a 'none' target has rules or actions we assume it requires a build.
+  return target_dict['type'] != 'none' or \
+      target_dict.get('actions') or target_dict.get('rules')
+
+
+def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files,
+                     build_files):
+  """Returns a tuple of the following:
+  . A dictionary mapping from fully qualified name to Target.
+  . A list of the targets that have a source file in |files|.
+  . Set of root Targets reachable from the the files |build_files|.
+  This sets the |match_status| of the targets that contain any of the source
+  files in |files| to MATCH_STATUS_MATCHES.
+  |toplevel_dir| is the root of the source tree."""
+  # Maps from target name to Target.
   targets = {}
 
+  # Targets that matched.
+  matching_targets = []
+
   # Queue of targets to visit.
   targets_to_visit = target_list[:]
 
+  # Maps from build file to a boolean indicating whether the build file is in
+  # |files|.
+  build_file_in_files = {}
+
+  # Root targets across all files.
+  roots = set()
+
+  # Set of Targets in |build_files|.
+  build_file_targets = set()
+
   while len(targets_to_visit) > 0:
-    absolute_target_name = targets_to_visit.pop()
-    # |absolute_target| may be an absolute path and may include #target.
-    # References to targets are relative, so we need to clean the name.
-    relative_target_name = __MakeRelativeTargetName(absolute_target_name)
-    if relative_target_name in targets:
+    target_name = targets_to_visit.pop()
+    created_target, target = _GetOrCreateTargetByName(targets, target_name)
+    if created_target:
+      roots.add(target)
+    elif target.visited:
       continue
 
-    target = Target()
-    targets[relative_target_name] = target
-    target.sources.extend(__ExtractSources(relative_target_name,
-                                           target_dicts[absolute_target_name]))
+    target.visited = True
+    target.requires_build = _DoesTargetTypeRequireBuild(
+        target_dicts[target_name])
+    target.is_executable = target_dicts[target_name]['type'] == 'executable'
 
-    for dep in target_dicts[absolute_target_name].get('dependencies', []):
-      targets[relative_target_name].deps.append(__MakeRelativeTargetName(dep))
+    build_file = gyp.common.ParseQualifiedTarget(target_name)[0]
+    if not build_file in build_file_in_files:
+      build_file_in_files[build_file] = \
+          _WasBuildFileModified(build_file, data, files, toplevel_dir)
+
+    if build_file in build_files:
+      build_file_targets.add(target)
+
+    # If a build file (or any of its included files) is modified we assume all
+    # targets in the file are modified.
+    if build_file_in_files[build_file]:
+      print 'matching target from modified build file', target_name
+      target.match_status = MATCH_STATUS_MATCHES
+      matching_targets.append(target)
+    else:
+      sources = _ExtractSources(target_name, target_dicts[target_name],
+                                toplevel_dir)
+      for source in sources:
+        if source in files:
+          print 'target', target_name, 'matches', source
+          target.match_status = MATCH_STATUS_MATCHES
+          matching_targets.append(target)
+          break
+
+    # Add dependencies to visit as well as updating back pointers for deps.
+    for dep in target_dicts[target_name].get('dependencies', []):
       targets_to_visit.append(dep)
 
-  return targets
+      created_dep_target, dep_target = _GetOrCreateTargetByName(targets, dep)
+      if not created_dep_target:
+        roots.discard(dep_target)
 
-def __GetFiles(params):
-  """Returns the list of files to analyze, or None if none specified."""
-  generator_flags = params.get('generator_flags', {})
-  file_path = generator_flags.get('file_path', None)
-  if not file_path:
-    return None
-  try:
-    f = open(file_path, 'r')
-    result = []
-    for file_name in f:
-      if file_name.endswith('\n'):
-        file_name = file_name[0:len(file_name) - 1]
-      if len(file_name):
-        result.append(file_name)
-    f.close()
+      target.deps.add(dep_target)
+      dep_target.back_deps.add(target)
+
+  return targets, matching_targets, roots & build_file_targets
+
+
+def _GetUnqualifiedToTargetMapping(all_targets, to_find):
+  """Returns a mapping (dictionary) from unqualified name to Target for all the
+  Targets in |to_find|."""
+  result = {}
+  if not to_find:
     return result
-  except IOError:
-    print 'Unable to open file', file_path
-  return None
+  to_find = set(to_find)
+  for target_name in all_targets.keys():
+    extracted = gyp.common.ParseQualifiedTarget(target_name)
+    if len(extracted) > 1 and extracted[1] in to_find:
+      to_find.remove(extracted[1])
+      result[extracted[1]] = all_targets[target_name]
+      if not to_find:
+        return result
+  return result
+
+
+def _DoesTargetDependOn(target):
+  """Returns true if |target| or any of its dependencies matches the supplied
+  set of paths. This updates |matches| of the Targets as it recurses.
+  target: the Target to look for."""
+  if target.match_status == MATCH_STATUS_DOESNT_MATCH:
+    return False
+  if target.match_status == MATCH_STATUS_MATCHES or \
+      target.match_status == MATCH_STATUS_MATCHES_BY_DEPENDENCY:
+    return True
+  for dep in target.deps:
+    if _DoesTargetDependOn(dep):
+      target.match_status = MATCH_STATUS_MATCHES_BY_DEPENDENCY
+      return True
+  target.match_status = MATCH_STATUS_DOESNT_MATCH
+  return False
+
+
+def _GetTargetsDependingOn(possible_targets):
+  """Returns the list of Targets in |possible_targets| that depend (either
+  directly on indirectly) on the matched targets.
+  possible_targets: targets to search from."""
+  found = []
+  for target in possible_targets:
+    if _DoesTargetDependOn(target):
+      found.append(target)
+  return found
+
+
+def _AddBuildTargets(target, roots, add_if_no_ancestor, result):
+  """Recurses through all targets that depend on |target|, adding all targets
+  that need to be built (and are in |roots|) to |result|.
+  roots: set of root targets.
+  add_if_no_ancestor: If true and there are no ancestors of |target| then add
+  |target| to |result|. |target| must still be in |roots|.
+  result: targets that need to be built are added here."""
+  if target.visited:
+    return
+
+  target.visited = True
+  target.in_roots = not target.back_deps and target in roots
+
+  for back_dep_target in target.back_deps:
+    _AddBuildTargets(back_dep_target, roots, False, result)
+    target.added_to_compile_targets |= back_dep_target.added_to_compile_targets
+    target.in_roots |= back_dep_target.in_roots
+
+  # Always add 'executable' targets. Even though they may be built by other
+  # targets that depend upon them it makes detection of what is going to be
+  # built easier.
+  if target.in_roots and \
+        (target.is_executable or
+         (not target.added_to_compile_targets and
+          (add_if_no_ancestor or target.requires_build))):
+    result.add(target)
+    target.added_to_compile_targets = True
+
+
+def _GetBuildTargets(matching_targets, roots):
+  """Returns the set of Targets that require a build.
+  matching_targets: targets that changed and need to be built.
+  roots: set of root targets in the build files to search from."""
+  result = set()
+  for target in matching_targets:
+    _AddBuildTargets(target, roots, True, result)
+  return result
+
+
+def _WriteOutput(params, **values):
+  """Writes the output, either to stdout or a file is specified."""
+  if 'error' in values:
+    print 'Error:', values['error']
+  if 'status' in values:
+    print values['status']
+  if 'targets' in values:
+    values['targets'].sort()
+    print 'Supplied targets that depend on changed files:'
+    for target in values['targets']:
+      print '\t', target
+  if 'build_targets' in values:
+    values['build_targets'].sort()
+    print 'Targets that require a build:'
+    for target in values['build_targets']:
+      print '\t', target
+
+  output_path = params.get('generator_flags', {}).get(
+      'analyzer_output_path', None)
+  if not output_path:
+    print json.dumps(values)
+    return
+  try:
+    f = open(output_path, 'w')
+    f.write(json.dumps(values) + '\n')
+    f.close()
+  except IOError as e:
+    print 'Error writing to output file', output_path, str(e)
+
+
+def _WasGypIncludeFileModified(params, files):
+  """Returns true if one of the files in |files| is in the set of included
+  files."""
+  if params['options'].includes:
+    for include in params['options'].includes:
+      if _ToGypPath(include) in files:
+        print 'Include file modified, assuming all changed', include
+        return True
+  return False
+
+
+def _NamesNotIn(names, mapping):
+  """Returns a list of the values in |names| that are not in |mapping|."""
+  return [name for name in names if name not in mapping]
+
+
+def _LookupTargets(names, mapping):
+  """Returns a list of the mapping[name] for each value in |names| that is in
+  |mapping|."""
+  return [mapping[name] for name in names if name in mapping]
+
 
 def CalculateVariables(default_variables, params):
   """Calculate additional variables for use in the build (called by gyp)."""
@@ -166,27 +492,74 @@
     default_variables.setdefault('OS', 'mac')
   elif flavor == 'win':
     default_variables.setdefault('OS', 'win')
+    # Copy additional generator configuration data from VS, which is shared
+    # by the Windows Ninja generator.
+    import gyp.generator.msvs as msvs_generator
+    generator_additional_non_configuration_keys = getattr(msvs_generator,
+        'generator_additional_non_configuration_keys', [])
+    generator_additional_path_sections = getattr(msvs_generator,
+        'generator_additional_path_sections', [])
+
+    gyp.msvs_emulation.CalculateCommonVariables(default_variables, params)
   else:
     operating_system = flavor
     if flavor == 'android':
       operating_system = 'linux'  # Keep this legacy behavior for now.
     default_variables.setdefault('OS', operating_system)
 
+
 def GenerateOutput(target_list, target_dicts, data, params):
   """Called by gyp as the final stage. Outputs results."""
-  files = __GetFiles(params)
-  if not files:
-    print 'Must specify files to analyze via file_path generator flag'
-    return
+  config = Config()
+  try:
+    config.Init(params)
+    if not config.files:
+      raise Exception('Must specify files to analyze via config_path generator '
+                      'flag')
 
-  targets = __GenerateTargets(target_list, target_dicts)
+    toplevel_dir = _ToGypPath(os.path.abspath(params['options'].toplevel_dir))
+    if debug:
+      print 'toplevel_dir', toplevel_dir
 
-  files_set = frozenset(files)
-  found_in_all_sources = 0
-  for target_name, target in targets.iteritems():
-    sources = files_set.intersection(target.sources)
-    if len(sources):
-      print 'Found dependency'
+    if _WasGypIncludeFileModified(params, config.files):
+      result_dict = { 'status': all_changed_string,
+                      'targets': list(config.targets) }
+      _WriteOutput(params, **result_dict)
       return
 
-  print 'No dependencies'
+    all_targets, matching_targets, roots = _GenerateTargets(
+      data, target_list, target_dicts, toplevel_dir, frozenset(config.files),
+      params['build_files'])
+
+    warning = None
+    unqualified_mapping = _GetUnqualifiedToTargetMapping(all_targets,
+                                                         config.targets)
+    if len(unqualified_mapping) != len(config.targets):
+      not_found = _NamesNotIn(config.targets, unqualified_mapping)
+      warning = 'Unable to find all targets: ' + str(not_found)
+
+    if matching_targets:
+      search_targets = _LookupTargets(config.targets, unqualified_mapping)
+      matched_search_targets = _GetTargetsDependingOn(search_targets)
+      # Reset the visited status for _GetBuildTargets.
+      for target in all_targets.itervalues():
+        target.visited = False
+      build_targets = _GetBuildTargets(matching_targets, roots)
+      matched_search_targets = [gyp.common.ParseQualifiedTarget(target.name)[1]
+                                for target in matched_search_targets]
+      build_targets = [gyp.common.ParseQualifiedTarget(target.name)[1]
+                       for target in build_targets]
+    else:
+      matched_search_targets = []
+      build_targets = []
+
+    result_dict = { 'targets': matched_search_targets,
+                    'status': found_dependency_string if matching_targets else
+                              no_dependency_string,
+                    'build_targets': build_targets}
+    if warning:
+      result_dict['warning'] = warning
+    _WriteOutput(params, **result_dict)
+
+  except Exception as e:
+    _WriteOutput(params, error=str(e))
diff --git a/pylib/gyp/generator/android.py b/pylib/gyp/generator/android.py
index 38af593..5afeb53 100644
--- a/pylib/gyp/generator/android.py
+++ b/pylib/gyp/generator/android.py
@@ -50,6 +50,8 @@
 generator_additional_non_configuration_keys = [
     # Boolean to declare that this target does not want its name mangled.
     'android_unmangled_name',
+    # Map of android build system variables to set.
+    'aosp_build_settings',
 ]
 generator_additional_path_sections = []
 generator_extra_sources_for_rules = []
@@ -66,33 +68,6 @@
 
 """
 
-android_standard_include_paths = set([
-    # JNI_H_INCLUDE in build/core/binary.mk
-    'dalvik/libnativehelper/include/nativehelper',
-    # from SRC_HEADERS in build/core/config.mk
-    'system/core/include',
-    'hardware/libhardware/include',
-    'hardware/libhardware_legacy/include',
-    'hardware/ril/include',
-    'dalvik/libnativehelper/include',
-    'frameworks/native/include',
-    'frameworks/native/opengl/include',
-    'frameworks/base/include',
-    'frameworks/base/opengl/include',
-    'frameworks/base/native/include',
-    'external/skia/include',
-    # TARGET_C_INCLUDES in build/core/combo/TARGET_linux-arm.mk
-    'bionic/libc/arch-arm/include',
-    'bionic/libc/include',
-    'bionic/libstdc++/include',
-    'bionic/libc/kernel/uapi',
-    'bionic/libc/kernel/uapi/asm-arm',
-    'bionic/libm/include',
-    'bionic/libm/include/arm',
-    'bionic/libthread_db/include',
-    ])
-
-
 # Map gyp target types to Android module classes.
 MODULE_CLASSES = {
     'static_library': 'STATIC_LIBRARIES',
@@ -185,7 +160,6 @@
     if self.android_stem != self.android_module:
       self.WriteLn('LOCAL_MODULE_STEM := ' + self.android_stem)
     self.WriteLn('LOCAL_MODULE_SUFFIX := ' + self.android_suffix)
-    self.WriteLn('LOCAL_MODULE_TAGS := optional')
     if self.toolset == 'host':
       self.WriteLn('LOCAL_IS_HOST_MODULE := true')
       self.WriteLn('LOCAL_MULTILIB := $(GYP_HOST_MULTILIB)')
@@ -503,16 +477,9 @@
 
       self.WriteLn('\n# Flags passed to only C++ (and not C) files.')
       self.WriteList(config.get('cflags_cc'), 'LOCAL_CPPFLAGS_%s' % configname)
-      if int(config.get('android_enable_fdo', 0)):
-        use_fdo = 'true'
-      else:
-        use_fdo = 'false'
-      self.WriteLn('\nLOCAL_FDO_SUPPORT_%s := %s' % (configname, use_fdo))
 
     self.WriteLn('\nLOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) '
                  '$(MY_DEFS_$(GYP_CONFIGURATION))')
-    self.WriteLn(
-        'LOCAL_FDO_SUPPORT := $(LOCAL_FDO_SUPPORT_$(GYP_CONFIGURATION))')
     # Undefine ANDROID for host modules
     # TODO: the source code should not use macro ANDROID to tell if it's host
     # or target module.
@@ -720,9 +687,7 @@
 
   def NormalizeIncludePaths(self, include_paths):
     """ Normalize include_paths.
-    Convert absolute paths to relative to the Android top directory;
-    filter out include paths that are already brought in by the Android build
-    system.
+    Convert absolute paths to relative to the Android top directory.
 
     Args:
       include_paths: A list of unprocessed include paths.
@@ -733,10 +698,7 @@
     for path in include_paths:
       if path[0] == '/':
         path = gyp.common.RelativePath(path, self.android_top_dir)
-
-      # Filter out the Android standard search path.
-      if path not in android_standard_include_paths:
-        normalized.append(path)
+      normalized.append(path)
     return normalized
 
   def ExtractIncludesFromCFlags(self, cflags):
@@ -817,28 +779,41 @@
     spec, configs: input from gyp.
     link_deps: link dependency list; see ComputeDeps()
     """
-    for configname, config in sorted(configs.iteritems()):
-      ldflags = list(config.get('ldflags', []))
-      self.WriteLn('')
-      self.WriteList(ldflags, 'LOCAL_LDFLAGS_%s' % configname)
-    self.WriteLn('\nLOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))')
+    if self.type != 'static_library':
+      for configname, config in sorted(configs.iteritems()):
+        ldflags = list(config.get('ldflags', []))
+        self.WriteLn('')
+        self.WriteList(ldflags, 'LOCAL_LDFLAGS_%s' % configname)
+      self.WriteLn('\nLOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))')
 
     # Libraries (i.e. -lfoo)
+    # These must be included even for static libraries as some of them provide
+    # implicit include paths through the build system.
     libraries = gyp.common.uniquer(spec.get('libraries', []))
     static_libs, dynamic_libs = self.ComputeAndroidLibraryModuleNames(
         libraries)
 
-    # Link dependencies (i.e. libfoo.a, libfoo.so)
-    static_link_deps = [x[1] for x in link_deps if x[0] == 'static']
-    shared_link_deps = [x[1] for x in link_deps if x[0] == 'shared']
-    self.WriteLn('')
-    self.WriteList(static_libs + static_link_deps,
-                   'LOCAL_STATIC_LIBRARIES')
-    self.WriteLn('# Enable grouping to fix circular references')
-    self.WriteLn('LOCAL_GROUP_STATIC_LIBRARIES := true')
-    self.WriteLn('')
-    self.WriteList(dynamic_libs + shared_link_deps,
-                   'LOCAL_SHARED_LIBRARIES')
+    # Link dependencies (i.e. other gyp targets this target depends on)
+    # These need not be included for static libraries as within the gyp build
+    # we do not use the implicit include path mechanism.
+    if self.type != 'static_library':
+      static_link_deps = [x[1] for x in link_deps if x[0] == 'static']
+      shared_link_deps = [x[1] for x in link_deps if x[0] == 'shared']
+    else:
+      static_link_deps = []
+      shared_link_deps = []
+
+    # Only write the lists if they are non-empty.
+    if static_libs or static_link_deps:
+      self.WriteLn('')
+      self.WriteList(static_libs + static_link_deps,
+                     'LOCAL_STATIC_LIBRARIES')
+      self.WriteLn('# Enable grouping to fix circular references')
+      self.WriteLn('LOCAL_GROUP_STATIC_LIBRARIES := true')
+    if dynamic_libs or shared_link_deps:
+      self.WriteLn('')
+      self.WriteList(dynamic_libs + shared_link_deps,
+                     'LOCAL_SHARED_LIBRARIES')
 
 
   def WriteTarget(self, spec, configs, deps, link_deps, part_of_all,
@@ -856,6 +831,16 @@
     if self.type != 'none':
       self.WriteTargetFlags(spec, configs, link_deps)
 
+    settings = spec.get('aosp_build_settings', {})
+    if settings:
+      self.WriteLn('### Set directly by aosp_build_settings.')
+      for k, v in settings.iteritems():
+        if isinstance(v, list):
+          self.WriteList(v, k)
+        else:
+          self.WriteLn('%s := %s' % (k, make.QuoteIfNecessary(v)))
+      self.WriteLn('')
+
     # Add to the set of targets which represent the gyp 'all' target. We use the
     # name 'gyp_all_modules' as the Android build system doesn't allow the use
     # of the Make target 'all' and because 'all_modules' is the equivalent of
diff --git a/pylib/gyp/generator/make.py b/pylib/gyp/generator/make.py
index b88a433..8c31d10 100644
--- a/pylib/gyp/generator/make.py
+++ b/pylib/gyp/generator/make.py
@@ -29,6 +29,7 @@
 import gyp.common
 import gyp.xcode_emulation
 from gyp.common import GetEnvironFallback
+from gyp.common import GypError
 
 generator_default_variables = {
   'EXECUTABLE_PREFIX': '',
@@ -631,6 +632,38 @@
   return s.replace(' ', quote)
 
 
+# TODO: Avoid code duplication with _ValidateSourcesForMSVSProject in msvs.py.
+def _ValidateSourcesForOSX(spec, all_sources):
+  """Makes sure if duplicate basenames are not specified in the source list.
+
+  Arguments:
+    spec: The target dictionary containing the properties of the target.
+  """
+  if spec.get('type', None) != 'static_library':
+    return
+
+  basenames = {}
+  for source in all_sources:
+    name, ext = os.path.splitext(source)
+    is_compiled_file = ext in [
+        '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S']
+    if not is_compiled_file:
+      continue
+    basename = os.path.basename(name)  # Don't include extension.
+    basenames.setdefault(basename, []).append(source)
+
+  error = ''
+  for basename, files in basenames.iteritems():
+    if len(files) > 1:
+      error += '  %s: %s\n' % (basename, ' '.join(files))
+
+  if error:
+    print('static library %s has several files with the same basename:\n' %
+          spec['target_name'] + error + 'libtool on OS X will generate' +
+          ' warnings for them.')
+    raise GypError('Duplicate basenames in sources section, see list above')
+
+
 # Map from qualified target to path to output.
 target_outputs = {}
 # Map from qualified target to any linkable output.  A subset
@@ -758,6 +791,10 @@
     # Sources.
     all_sources = spec.get('sources', []) + extra_sources
     if all_sources:
+      if self.flavor == 'mac':
+        # libtool on OS X generates warnings for duplicate basenames in the same
+        # target.
+        _ValidateSourcesForOSX(spec, all_sources)
       self.WriteSources(
           configs, deps, all_sources, extra_outputs,
           extra_link_deps, part_of_all,
diff --git a/pylib/gyp/generator/msvs.py b/pylib/gyp/generator/msvs.py
index b18bff1..80e3104 100644
--- a/pylib/gyp/generator/msvs.py
+++ b/pylib/gyp/generator/msvs.py
@@ -921,6 +921,42 @@
     return _GenerateMSVSProject(project, options, version, generator_flags)
 
 
+# TODO: Avoid code duplication with _ValidateSourcesForOSX in make.py.
+def _ValidateSourcesForMSVSProject(spec, version):
+  """Makes sure if duplicate basenames are not specified in the source list.
+
+  Arguments:
+    spec: The target dictionary containing the properties of the target.
+    version: The VisualStudioVersion object.
+  """
+  # This validation should not be applied to MSVC2010 and later.
+  assert not version.UsesVcxproj()
+
+  # TODO: Check if MSVC allows this for loadable_module targets.
+  if spec.get('type', None) not in ('static_library', 'shared_library'):
+    return
+  sources = spec.get('sources', [])
+  basenames = {}
+  for source in sources:
+    name, ext = os.path.splitext(source)
+    is_compiled_file = ext in [
+        '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S']
+    if not is_compiled_file:
+      continue
+    basename = os.path.basename(name)  # Don't include extension.
+    basenames.setdefault(basename, []).append(source)
+
+  error = ''
+  for basename, files in basenames.iteritems():
+    if len(files) > 1:
+      error += '  %s: %s\n' % (basename, ' '.join(files))
+
+  if error:
+    print('static library %s has several files with the same basename:\n' %
+          spec['target_name'] + error + 'MSVC08 cannot handle that.')
+    raise GypError('Duplicate basenames in sources section, see list above')
+
+
 def _GenerateMSVSProject(project, options, version, generator_flags):
   """Generates a .vcproj file.  It may create .rules and .user files too.
 
@@ -946,6 +982,11 @@
   for config_name, config in spec['configurations'].iteritems():
     _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config)
 
+  # MSVC08 and prior version cannot handle duplicate basenames in the same
+  # target.
+  # TODO: Take excluded sources into consideration if possible.
+  _ValidateSourcesForMSVSProject(spec, version)
+
   # Prepare list of sources and excluded sources.
   gyp_file = os.path.split(project.build_file)[1]
   sources, excluded_sources = _PrepareListOfSources(spec, generator_flags,
@@ -3287,8 +3328,8 @@
     # get too long. See also _AddActions: cygwin's setup_env mustn't be called
     # for every invocation or the command that sets the PATH will grow too
     # long.
-    command = (
-        '\r\nif %errorlevel% neq 0 exit /b %errorlevel%\r\n'.join(commands))
+    command = '\r\n'.join([c + '\r\nif %errorlevel% neq 0 exit /b %errorlevel%'
+                           for c in commands])
     _AddMSBuildAction(spec,
                       primary_input,
                       inputs,
diff --git a/pylib/gyp/generator/ninja.py b/pylib/gyp/generator/ninja.py
index f31068a..4484f93 100644
--- a/pylib/gyp/generator/ninja.py
+++ b/pylib/gyp/generator/ninja.py
@@ -14,6 +14,7 @@
 import sys
 import gyp
 import gyp.common
+from gyp.common import OrderedSet
 import gyp.msvs_emulation
 import gyp.MSVSUtil as MSVSUtil
 import gyp.xcode_emulation
@@ -529,7 +530,7 @@
   def WriteWinIdlFiles(self, spec, prebuild):
     """Writes rules to match MSVS's implicit idl handling."""
     assert self.flavor == 'win'
-    if self.msvs_settings.HasExplicitIdlRules(spec):
+    if self.msvs_settings.HasExplicitIdlRulesOrActions(spec):
       return []
     outputs = []
     for source in filter(lambda x: x.endswith('.idl'), spec['sources']):
@@ -598,8 +599,9 @@
       is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action)
                    if self.flavor == 'win' else False)
       args = action['action']
+      pool = 'console' if int(action.get('ninja_use_console', 0)) else None
       rule_name, _ = self.WriteNewNinjaRule(name, args, description,
-                                            is_cygwin, env=env)
+                                            is_cygwin, env, pool)
 
       inputs = [self.GypPathToNinja(i, env) for i in action['inputs']]
       if int(action.get('process_outputs_as_sources', False)):
@@ -637,8 +639,9 @@
           ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name)
       is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule)
                    if self.flavor == 'win' else False)
+      pool = 'console' if int(rule.get('ninja_use_console', 0)) else None
       rule_name, args = self.WriteNewNinjaRule(
-          name, args, description, is_cygwin, env=env)
+          name, args, description, is_cygwin, env, pool)
 
       # TODO: if the command references the outputs directly, we should
       # simplify it to just use $out.
@@ -802,6 +805,8 @@
       self.ninja.variable('cxx', '$cxx_host')
       self.ninja.variable('ld', '$ld_host')
       self.ninja.variable('ldxx', '$ldxx_host')
+      self.ninja.variable('nm', '$nm_host')
+      self.ninja.variable('readelf', '$readelf_host')
 
     if self.flavor != 'mac' or len(self.archs) == 1:
       return self.WriteSourcesForArch(
@@ -1426,7 +1431,7 @@
       values = []
     ninja_file.variable(var, ' '.join(values))
 
-  def WriteNewNinjaRule(self, name, args, description, is_cygwin, env):
+  def WriteNewNinjaRule(self, name, args, description, is_cygwin, env, pool):
     """Write out a new ninja "rule" statement for a given command.
 
     Returns the name of the new rule, and a copy of |args| with variables
@@ -1484,7 +1489,7 @@
     # GYP rules/actions express being no-ops by not touching their outputs.
     # Avoid executing downstream dependencies in this case by specifying
     # restat=1 to ninja.
-    self.ninja.rule(rule_name, command, description, restat=True,
+    self.ninja.rule(rule_name, command, description, restat=True, pool=pool,
                     rspfile=rspfile, rspfile_content=rspfile_content)
     self.ninja.newline()
 
@@ -1739,6 +1744,10 @@
   cc_host_global_setting = None
   cxx_host_global_setting = None
   clang_cl = None
+  nm = 'nm'
+  nm_host = 'nm'
+  readelf = 'readelf'
+  readelf_host = 'readelf'
 
   build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
   make_global_settings = data[build_file].get('make_global_settings', [])
@@ -1766,6 +1775,14 @@
       ld = os.path.join(build_to_root, value)
     if key == 'LD.host':
       ld_host = os.path.join(build_to_root, value)
+    if key == 'NM':
+      nm = os.path.join(build_to_root, value)
+    if key == 'NM.host':
+      nm_host = os.path.join(build_to_root, value)
+    if key == 'READELF':
+      readelf = os.path.join(build_to_root, value)
+    if key == 'READELF.host':
+      readelf_host = os.path.join(build_to_root, value)
     if key.endswith('_wrapper'):
       wrappers[key[:-len('_wrapper')]] = os.path.join(build_to_root, value)
 
@@ -1777,8 +1794,15 @@
       wrappers[key_prefix] = os.path.join(build_to_root, value)
 
   if flavor == 'win':
+    configs = [target_dicts[qualified_target]['configurations'][config_name]
+               for qualified_target in target_list]
+    shared_system_includes = None
+    if not generator_flags.get('ninja_use_custom_environment_files', 0):
+      shared_system_includes = \
+          gyp.msvs_emulation.ExtractSharedMSVSSystemIncludes(
+              configs, generator_flags)
     cl_paths = gyp.msvs_emulation.GenerateEnvironmentFiles(
-        toplevel_build, generator_flags, OpenOutput)
+        toplevel_build, generator_flags, shared_system_includes, OpenOutput)
     for arch, path in cl_paths.iteritems():
       if clang_cl:
         # If we have selected clang-cl, use that instead.
@@ -1806,6 +1830,13 @@
     master_ninja.variable('ld', CommandWithWrapper('LINK', wrappers, ld))
     master_ninja.variable('ldxx', CommandWithWrapper('LINK', wrappers, ldxx))
     master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], ar))
+    if flavor != 'mac':
+      # Mac does not use readelf/nm for .TOC generation, so avoiding polluting
+      # the master ninja with extra unused variables.
+      master_ninja.variable(
+          'nm', GetEnvironFallback(['NM_target', 'NM'], nm))
+      master_ninja.variable(
+          'readelf', GetEnvironFallback(['READELF_target', 'READELF'], readelf))
 
   if generator_supports_multiple_toolsets:
     if not cc_host:
@@ -1814,6 +1845,9 @@
       cxx_host = cxx
 
     master_ninja.variable('ar_host', GetEnvironFallback(['AR_host'], ar_host))
+    master_ninja.variable('nm_host', GetEnvironFallback(['NM_host'], nm_host))
+    master_ninja.variable('readelf_host',
+                          GetEnvironFallback(['READELF_host'], readelf_host))
     cc_host = GetEnvironFallback(['CC_host'], cc_host)
     cxx_host = GetEnvironFallback(['CXX_host'], cxx_host)
 
@@ -1935,8 +1969,8 @@
         % { 'solink':
               '$ld -shared $ldflags -o $lib -Wl,-soname=$soname %(suffix)s',
             'extract_toc':
-              ('{ readelf -d $lib | grep SONAME ; '
-               'nm -gD -f p $lib | cut -f1-2 -d\' \'; }')})
+              ('{ $readelf -d $lib | grep SONAME ; '
+               '$nm -gD -f p $lib | cut -f1-2 -d\' \'; }')})
 
     master_ninja.rule(
       'solink',
@@ -2116,6 +2150,15 @@
   # objects.
   target_short_names = {}
 
+  # short name of targets that were skipped because they didn't contain anything
+  # interesting.
+  # NOTE: there may be overlap between this an non_empty_target_names.
+  empty_target_names = set()
+
+  # Set of non-empty short target names.
+  # NOTE: there may be overlap between this an empty_target_names.
+  non_empty_target_names = set()
+
   for qualified_target in target_list:
     # qualified_target is like: third_party/icu/icu.gyp:icui18n#target
     build_file, name, toolset = \
@@ -2159,6 +2202,9 @@
       target_outputs[qualified_target] = target
       if qualified_target in all_targets:
         all_outputs.add(target.FinalOutput())
+      non_empty_target_names.add(name)
+    else:
+      empty_target_names.add(name)
 
   if target_short_names:
     # Write a short name to build this target.  This benefits both the
@@ -2170,6 +2216,16 @@
       master_ninja.build(short_name, 'phony', [x.FinalOutput() for x in
                                                target_short_names[short_name]])
 
+  # Write phony targets for any empty targets that weren't written yet. As
+  # short names are  not necessarily unique only do this for short names that
+  # haven't already been output for another target.
+  empty_target_names = empty_target_names - non_empty_target_names
+  if empty_target_names:
+    master_ninja.newline()
+    master_ninja.comment('Empty targets (output for completeness).')
+    for name in sorted(empty_target_names):
+      master_ninja.build(name, 'phony')
+
   if all_outputs:
     master_ninja.newline()
     master_ninja.build('all', 'phony', list(all_outputs))
diff --git a/pylib/gyp/generator/xcode.py b/pylib/gyp/generator/xcode.py
index 7972459..b4d1e19 100644
--- a/pylib/gyp/generator/xcode.py
+++ b/pylib/gyp/generator/xcode.py
@@ -69,6 +69,7 @@
 # The Xcode-specific keys that exist on targets and aren't moved down to
 # configurations.
 generator_additional_non_configuration_keys = [
+  'ios_app_extension',
   'mac_bundle',
   'mac_bundle_resources',
   'mac_framework_headers',
@@ -644,14 +645,15 @@
     # com.googlecode.gyp.xcode.bundle, a pseudo-type that xcode.py interprets
     # to create a single-file mh_bundle.
     _types = {
-      'executable':             'com.apple.product-type.tool',
-      'loadable_module':        'com.googlecode.gyp.xcode.bundle',
-      'shared_library':         'com.apple.product-type.library.dynamic',
-      'static_library':         'com.apple.product-type.library.static',
-      'executable+bundle':      'com.apple.product-type.application',
-      'loadable_module+bundle': 'com.apple.product-type.bundle',
-      'loadable_module+xctest': 'com.apple.product-type.bundle.unit-test',
-      'shared_library+bundle':  'com.apple.product-type.framework',
+      'executable':                  'com.apple.product-type.tool',
+      'loadable_module':             'com.googlecode.gyp.xcode.bundle',
+      'shared_library':              'com.apple.product-type.library.dynamic',
+      'static_library':              'com.apple.product-type.library.static',
+      'executable+bundle':           'com.apple.product-type.application',
+      'loadable_module+bundle':      'com.apple.product-type.bundle',
+      'loadable_module+xctest':      'com.apple.product-type.bundle.unit-test',
+      'shared_library+bundle':       'com.apple.product-type.framework',
+      'executable+extension+bundle': 'com.apple.product-type.app-extension',
     }
 
     target_properties = {
@@ -662,6 +664,7 @@
     type = spec['type']
     is_xctest = int(spec.get('mac_xctest_bundle', 0))
     is_bundle = int(spec.get('mac_bundle', 0)) or is_xctest
+    is_extension = int(spec.get('ios_app_extension', 0))
     if type != 'none':
       type_bundle_key = type
       if is_xctest:
@@ -669,6 +672,10 @@
         assert type == 'loadable_module', (
             'mac_xctest_bundle targets must have type loadable_module '
             '(target %s)' % target_name)
+      elif is_extension:
+        assert is_bundle, ('ios_app_extension flag requires mac_bundle '
+            '(target %s)' % target_name)
+        type_bundle_key += '+extension+bundle'
       elif is_bundle:
         type_bundle_key += '+bundle'
 
diff --git a/pylib/gyp/input.py b/pylib/gyp/input.py
index b09a2c8..bb853a5 100644
--- a/pylib/gyp/input.py
+++ b/pylib/gyp/input.py
@@ -994,23 +994,29 @@
     # Prepare for the next match iteration.
     input_str = output
 
-  # Look for more matches now that we've replaced some, to deal with
-  # expanding local variables (variables defined in the same
-  # variables block as this one).
-  gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output)
-  if type(output) is list:
-    if output and type(output[0]) is list:
-      # Leave output alone if it's a list of lists.
-      # We don't want such lists to be stringified.
-      pass
-    else:
-      new_output = []
-      for item in output:
-        new_output.append(
-            ExpandVariables(item, phase, variables, build_file))
-      output = new_output
+  if output == input:
+    gyp.DebugOutput(gyp.DEBUG_VARIABLES,
+                    "Found only identity matches on %r, avoiding infinite "
+                    "recursion.",
+                    output)
   else:
-    output = ExpandVariables(output, phase, variables, build_file)
+    # Look for more matches now that we've replaced some, to deal with
+    # expanding local variables (variables defined in the same
+    # variables block as this one).
+    gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output)
+    if type(output) is list:
+      if output and type(output[0]) is list:
+        # Leave output alone if it's a list of lists.
+        # We don't want such lists to be stringified.
+        pass
+      else:
+        new_output = []
+        for item in output:
+          new_output.append(
+              ExpandVariables(item, phase, variables, build_file))
+        output = new_output
+    else:
+      output = ExpandVariables(output, phase, variables, build_file)
 
   # Convert all strings that are canonically-represented integers into integers.
   if type(output) is list:
@@ -2463,7 +2469,10 @@
                                                              target_type))
 
 
-def ValidateSourcesInTarget(target, target_dict, build_file):
+def ValidateSourcesInTarget(target, target_dict, build_file,
+                            duplicate_basename_check):
+  if not duplicate_basename_check:
+    return
   # TODO: Check if MSVC allows this for loadable_module targets.
   if target_dict.get('type', None) not in ('static_library', 'shared_library'):
     return
@@ -2485,8 +2494,9 @@
 
   if error:
     print('static library %s has several files with the same basename:\n' %
-          target + error + 'Some build systems, e.g. MSVC08, '
-          'cannot handle that.')
+          target + error + 'Some build systems, e.g. MSVC08 and Make generator '
+          'for Mac, cannot handle that. Use --no-duplicate-basename-check to'
+          'disable this validation.')
     raise GypError('Duplicate basenames in sources section, see list above')
 
 
@@ -2710,7 +2720,7 @@
 
 
 def Load(build_files, variables, includes, depth, generator_input_info, check,
-         circular_check, parallel, root_targets):
+         circular_check, duplicate_basename_check, parallel, root_targets):
   SetGeneratorGlobals(generator_input_info)
   # A generator can have other lists (in addition to sources) be processed
   # for rules.
@@ -2835,6 +2845,11 @@
     ProcessVariablesAndConditionsInDict(
         target_dict, PHASE_LATELATE, variables, build_file)
 
+  # TODO(thakis): Get vpx_scale/arm/scalesystemdependent.c to be renamed to
+  #               scalesystemdependent_arm_additions.c or similar.
+  if 'arm' in variables.get('target_arch', ''):
+    duplicate_basename_check = False
+
   # Make sure that the rules make sense, and build up rule_sources lists as
   # needed.  Not all generators will need to use the rule_sources lists, but
   # some may, and it seems best to build the list in a common spot.
@@ -2843,10 +2858,8 @@
     target_dict = targets[target]
     build_file = gyp.common.BuildFile(target)
     ValidateTargetType(target, target_dict)
-    # TODO(thakis): Get vpx_scale/arm/scalesystemdependent.c to be renamed to
-    #               scalesystemdependent_arm_additions.c or similar.
-    if 'arm' not in variables.get('target_arch', ''):
-      ValidateSourcesInTarget(target, target_dict, build_file)
+    ValidateSourcesInTarget(target, target_dict, build_file,
+                            duplicate_basename_check)
     ValidateRulesInTarget(target, target_dict, extra_sources_for_rules)
     ValidateRunAsInTarget(target, target_dict, build_file)
     ValidateActionsInTarget(target, target_dict, build_file)
diff --git a/pylib/gyp/msvs_emulation.py b/pylib/gyp/msvs_emulation.py
index 63593a4..5384df1 100644
--- a/pylib/gyp/msvs_emulation.py
+++ b/pylib/gyp/msvs_emulation.py
@@ -12,6 +12,7 @@
 import subprocess
 import sys
 
+from gyp.common import OrderedSet
 import gyp.MSVSVersion
 
 windows_quoter_regex = re.compile(r'(\\*)"')
@@ -131,6 +132,54 @@
   return dxsdk_dir
 
 
+def GetGlobalVSMacroEnv(vs_version):
+  """Get a dict of variables mapping internal VS macro names to their gyp
+  equivalents. Returns all variables that are independent of the target."""
+  env = {}
+  # '$(VSInstallDir)' and '$(VCInstallDir)' are available when and only when
+  # Visual Studio is actually installed.
+  if vs_version.Path():
+    env['$(VSInstallDir)'] = vs_version.Path()
+    env['$(VCInstallDir)'] = os.path.join(vs_version.Path(), 'VC') + '\\'
+  # Chromium uses DXSDK_DIR in include/lib paths, but it may or may not be
+  # set. This happens when the SDK is sync'd via src-internal, rather than
+  # by typical end-user installation of the SDK. If it's not set, we don't
+  # want to leave the unexpanded variable in the path, so simply strip it.
+  dxsdk_dir = _FindDirectXInstallation()
+  env['$(DXSDK_DIR)'] = dxsdk_dir if dxsdk_dir else ''
+  # Try to find an installation location for the Windows DDK by checking
+  # the WDK_DIR environment variable, may be None.
+  env['$(WDK_DIR)'] = os.environ.get('WDK_DIR', '')
+  return env
+
+def ExtractSharedMSVSSystemIncludes(configs, generator_flags):
+  """Finds msvs_system_include_dirs that are common to all targets, removes
+  them from all targets, and returns an OrderedSet containing them."""
+  all_system_includes = OrderedSet(
+      configs[0].get('msvs_system_include_dirs', []))
+  for config in configs[1:]:
+    system_includes = config.get('msvs_system_include_dirs', [])
+    all_system_includes = all_system_includes & OrderedSet(system_includes)
+  if not all_system_includes:
+    return None
+  # Expand macros in all_system_includes.
+  env = GetGlobalVSMacroEnv(GetVSVersion(generator_flags))
+  expanded_system_includes = OrderedSet([ExpandMacros(include, env)
+                                         for include in all_system_includes])
+  if any(['$' in include for include in expanded_system_includes]):
+    # Some path relies on target-specific variables, bail.
+    return None
+
+  # Remove system includes shared by all targets from the targets.
+  for config in configs:
+    includes = config.get('msvs_system_include_dirs', [])
+    if includes:  # Don't insert a msvs_system_include_dirs key if not needed.
+      # This must check the unexpanded includes list:
+      new_includes = [i for i in includes if i not in all_system_includes]
+      config['msvs_system_include_dirs'] = new_includes
+  return expanded_system_includes
+
+
 class MsvsSettings(object):
   """A class that understands the gyp 'msvs_...' values (especially the
   msvs_settings field). They largely correpond to the VS2008 IDE DOM. This
@@ -139,11 +188,6 @@
   def __init__(self, spec, generator_flags):
     self.spec = spec
     self.vs_version = GetVSVersion(generator_flags)
-    self.dxsdk_dir = _FindDirectXInstallation()
-
-    # Try to find an installation location for the Windows DDK by checking
-    # the WDK_DIR environment variable, may be None.
-    self.wdk_dir = os.environ.get('WDK_DIR')
 
     supported_fields = [
         ('msvs_configuration_attributes', dict),
@@ -194,18 +238,7 @@
         '$(PlatformName)': target_platform,
         '$(ProjectDir)\\': '',
     }
-    # '$(VSInstallDir)' and '$(VCInstallDir)' are available when and only when
-    # Visual Studio is actually installed.
-    if self.vs_version.Path():
-      replacements['$(VSInstallDir)'] = self.vs_version.Path()
-      replacements['$(VCInstallDir)'] = os.path.join(self.vs_version.Path(),
-                                                     'VC') + '\\'
-    # Chromium uses DXSDK_DIR in include/lib paths, but it may or may not be
-    # set. This happens when the SDK is sync'd via src-internal, rather than
-    # by typical end-user installation of the SDK. If it's not set, we don't
-    # want to leave the unexpanded variable in the path, so simply strip it.
-    replacements['$(DXSDK_DIR)'] = self.dxsdk_dir if self.dxsdk_dir else ''
-    replacements['$(WDK_DIR)'] = self.wdk_dir if self.wdk_dir else ''
+    replacements.update(GetGlobalVSMacroEnv(self.vs_version))
     return replacements
 
   def ConvertVSMacros(self, s, base_to_build=None, config=None):
@@ -337,7 +370,7 @@
     output_file = self._Setting(('VCLinkerTool', 'ProgramDatabaseFile'), config)
     generate_debug_info = self._Setting(
         ('VCLinkerTool', 'GenerateDebugInformation'), config)
-    if generate_debug_info:
+    if generate_debug_info == 'true':
       if output_file:
         return expand_special(self.ConvertVSMacros(output_file, config=config))
       else:
@@ -727,10 +760,16 @@
         return True
     return False
 
-  def HasExplicitIdlRules(self, spec):
-    """Determine if there's an explicit rule for idl files. When there isn't we
-    need to generate implicit rules to build MIDL .idl files."""
-    return self._HasExplicitRuleForExtension(spec, 'idl')
+  def _HasExplicitIdlActions(self, spec):
+    """Determine if an action should not run midl for .idl files."""
+    return any([action.get('explicit_idl_action', 0)
+                for action in spec.get('actions', [])])
+
+  def HasExplicitIdlRulesOrActions(self, spec):
+    """Determine if there's an explicit rule or action for idl files. When
+    there isn't we need to generate implicit rules to build MIDL .idl files."""
+    return (self._HasExplicitRuleForExtension(spec, 'idl') or
+            self._HasExplicitIdlActions(spec))
 
   def HasExplicitAsmRules(self, spec):
     """Determine if there's an explicit rule for asm files. When there isn't we
@@ -897,7 +936,8 @@
     if line.startswith('LOC:'):
       return line[len('LOC:'):].strip()
 
-def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags, open_out):
+def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags,
+                             system_includes, open_out):
   """It's not sufficient to have the absolute path to the compiler, linker,
   etc. on Windows, as those tools rely on .dlls being in the PATH. We also
   need to support both x86 and x64 compilers within the same build (to support
@@ -928,6 +968,13 @@
         args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     variables, _ = popen.communicate()
     env = _ExtractImportantEnvironment(variables)
+
+    # Inject system includes from gyp files into INCLUDE.
+    if system_includes:
+      system_includes = system_includes | OrderedSet(
+                                              env.get('INCLUDE', '').split(';'))
+      env['INCLUDE'] = ';'.join(system_includes)
+
     env_block = _FormatAsEnvironmentBlock(env)
     f = open_out(os.path.join(toplevel_build_dir, 'environment.' + arch), 'wb')
     f.write(env_block)
diff --git a/pylib/gyp/xcode_emulation.py b/pylib/gyp/xcode_emulation.py
index 859cd5a..2f34bc6 100644
--- a/pylib/gyp/xcode_emulation.py
+++ b/pylib/gyp/xcode_emulation.py
@@ -218,6 +218,9 @@
   def _IsBundle(self):
     return int(self.spec.get('mac_bundle', 0)) != 0
 
+  def _IsIosAppExtension(self):
+    return int(self.spec.get('ios_app_extension', 0)) != 0
+
   def GetFrameworkVersion(self):
     """Returns the framework version of the current target. Only valid for
     bundles."""
@@ -237,7 +240,10 @@
           'WRAPPER_EXTENSION', default=default_wrapper_extension)
       return '.' + self.spec.get('product_extension', wrapper_extension)
     elif self.spec['type'] == 'executable':
-      return '.' + self.spec.get('product_extension', 'app')
+      if self._IsIosAppExtension():
+        return '.' + self.spec.get('product_extension', 'appex')
+      else:
+        return '.' + self.spec.get('product_extension', 'app')
     else:
       assert False, "Don't know extension for '%s', target '%s'" % (
           self.spec['type'], self.spec['target_name'])
@@ -292,6 +298,10 @@
 
   def GetProductType(self):
     """Returns the PRODUCT_TYPE of this target."""
+    if self._IsIosAppExtension():
+      assert self._IsBundle(), ('ios_app_extension flag requires mac_bundle '
+          '(target %s)' % self.spec['target_name'])
+      return 'com.apple.product-type.app-extension'
     if self._IsBundle():
       return {
         'executable': 'com.apple.product-type.application',
@@ -794,6 +804,18 @@
     for directory in framework_dirs:
       ldflags.append('-F' + directory.replace('$(SDKROOT)', sdk_root))
 
+    if sdk_root and self._IsIosAppExtension():
+      # Adds the link flags for extensions. These flags are common for all
+      # extensions and provide loader and main function.
+      # These flags reflect the compilation options used by xcode to compile
+      # extensions.
+      ldflags.append('-lpkstart')
+      ldflags.append(sdk_root +
+          '/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit')
+      ldflags.append('-fapplication-extension')
+      ldflags.append('-Xlinker -rpath '
+          '-Xlinker @executable_path/../../Frameworks')
+
     self._Appendf(ldflags, 'CLANG_CXX_LIBRARY', '-stdlib=%s')
 
     self.configname = None
@@ -921,7 +943,7 @@
     """Return a shell command to codesign the iOS output binary so it can
     be deployed to a device.  This should be run as the very last step of the
     build."""
-    if not (self.isIOS and self.spec['type'] == "executable"):
+    if not (self.isIOS and self.spec['type'] == 'executable'):
       return []
 
     settings = self.xcode_settings[configname]
diff --git a/pylib/gyp/xcode_ninja.py b/pylib/gyp/xcode_ninja.py
index 0e5a70c..a005dfd 100644
--- a/pylib/gyp/xcode_ninja.py
+++ b/pylib/gyp/xcode_ninja.py
@@ -80,7 +80,8 @@
 
   if 'configurations' in old_spec:
     for config in old_spec['configurations'].iterkeys():
-      old_xcode_settings = old_spec['configurations'][config]['xcode_settings']
+      old_xcode_settings = \
+        old_spec['configurations'][config].get('xcode_settings', {})
       if 'IPHONEOS_DEPLOYMENT_TARGET' in old_xcode_settings:
         new_xcode_settings['CODE_SIGNING_REQUIRED'] = "NO"
         new_xcode_settings['IPHONEOS_DEPLOYMENT_TARGET'] = \
@@ -90,6 +91,7 @@
           new_xcode_settings
 
   ninja_target['mac_bundle'] = old_spec.get('mac_bundle', 0)
+  ninja_target['ios_app_extension'] = old_spec.get('ios_app_extension', 0)
   ninja_target['type'] = old_spec['type']
   if ninja_toplevel:
     ninja_target['actions'] = [
diff --git a/pylib/gyp/xcodeproj_file.py b/pylib/gyp/xcodeproj_file.py
index 79c3abc..7c7f1fb 100644
--- a/pylib/gyp/xcodeproj_file.py
+++ b/pylib/gyp/xcodeproj_file.py
@@ -1512,6 +1512,7 @@
         'xcassets':    'folder.assetcatalog',
         'xcconfig':    'text.xcconfig',
         'xcdatamodel': 'wrapper.xcdatamodel',
+        'xcdatamodeld':'wrapper.xcdatamodeld',
         'xib':         'file.xib',
         'y':           'sourcecode.yacc',
       }
@@ -2237,10 +2238,12 @@
   # Mapping from Xcode product-types to settings.  The settings are:
   #  filetype : used for explicitFileType in the project file
   #  prefix : the prefix for the file name
-  #  suffix : the suffix for the filen ame
+  #  suffix : the suffix for the file name
   _product_filetypes = {
     'com.apple.product-type.application':       ['wrapper.application',
                                                  '', '.app'],
+    'com.apple.product-type.app-extension':     ['wrapper.app-extension',
+                                                 '', '.appex'],
     'com.apple.product-type.bundle':            ['wrapper.cfbundle',
                                                  '', '.bundle'],
     'com.apple.product-type.framework':         ['wrapper.framework',
@@ -2313,11 +2316,11 @@
 
         if force_extension is not None:
           # If it's a wrapper (bundle), set WRAPPER_EXTENSION.
+          # Extension override.
+          suffix = '.' + force_extension
           if filetype.startswith('wrapper.'):
             self.SetBuildSetting('WRAPPER_EXTENSION', force_extension)
           else:
-            # Extension override.
-            suffix = '.' + force_extension
             self.SetBuildSetting('EXECUTABLE_EXTENSION', force_extension)
 
           if filetype.startswith('compiled.mach-o.executable'):
diff --git a/test/analyzer/common.gypi b/test/analyzer/common.gypi
new file mode 100644
index 0000000..7c664e4
--- /dev/null
+++ b/test/analyzer/common.gypi
@@ -0,0 +1,6 @@
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+}
diff --git a/test/analyzer/gyptest-analyzer.py b/test/analyzer/gyptest-analyzer.py
index a42748f..378996a 100644
--- a/test/analyzer/gyptest-analyzer.py
+++ b/test/analyzer/gyptest-analyzer.py
@@ -6,71 +6,350 @@
 """Tests for analyzer
 """
 
+import json
 import TestGyp
 
-found = 'Found dependency\n'
-not_found = 'No dependencies\n'
+found = 'Found dependency'
+found_all = 'Found dependency (all)'
+not_found = 'No dependencies'
 
-def __CreateTestFile(files):
+
+def _CreateConfigFile(files, targets):
+  """Creates the analyzer conflig file, which is used as the input to analyzer.
+  See description of analyzer.py for description of the arguments."""
   f = open('test_file', 'w')
-  for file in files:
-    f.write(file + '\n')
+  to_write = {'files': files, 'targets': targets }
+  json.dump(to_write, f)
   f.close()
 
+
+def _CreateBogusConfigFile():
+  f = open('test_file','w')
+  f.write('bogus')
+  f.close()
+
+
+def _ReadOutputFileContents():
+  f = open('analyzer_output', 'r')
+  result = json.load(f)
+  f.close()
+  return result
+
+
+# NOTE: this would be clearer if it subclassed TestGypCustom, but that trips
+# over a bug in pylint (E1002).
 test = TestGyp.TestGypCustom(format='analyzer')
 
-# Verifies file_path must be specified.
-test.run_gyp('test.gyp',
-             stdout='Must specify files to analyze via file_path generator '
-             'flag\n')
+def CommonArgs():
+  return ('-Gconfig_path=test_file',
+           '-Ganalyzer_output_path=analyzer_output')
+
+
+def run_analyzer(*args, **kw):
+  """Runs the test specifying a particular config and output path."""
+  args += CommonArgs()
+  test.run_gyp('test.gyp', *args, **kw)
+
+
+def run_analyzer2(*args, **kw):
+  """Same as run_analyzer(), but passes in test2.gyp instead of test.gyp."""
+  args += CommonArgs()
+  test.run_gyp('test2.gyp', *args, **kw)
+
+
+def run_analyzer3(*args, **kw):
+  """Same as run_analyzer(), but passes in test3.gyp instead of test.gyp."""
+  args += CommonArgs()
+  test.run_gyp('test3.gyp', *args, **kw)
+
+
+def run_analyzer4(*args, **kw):
+  """Same as run_analyzer(), but passes in test3.gyp instead of test.gyp."""
+  args += CommonArgs()
+  test.run_gyp('test4.gyp', *args, **kw)
+
+
+def EnsureContains(targets=set(), matched=False, build_targets=set()):
+  """Verifies output contains |targets|."""
+  result = _ReadOutputFileContents()
+  if result.get('error', None):
+    print 'unexpected error', result.get('error')
+    test.fail_test()
+
+  if result.get('warning', None):
+    print 'unexpected warning', result.get('warning')
+    test.fail_test()
+
+  actual_targets = set(result['targets'])
+  if actual_targets != targets:
+    print 'actual targets:', actual_targets, '\nexpected targets:', targets
+    test.fail_test()
+
+  actual_build_targets = set(result['build_targets'])
+  if actual_build_targets != build_targets:
+    print 'actual build_targets:', actual_build_targets, \
+           '\nexpected build_targets:', build_targets
+    test.fail_test()
+
+  if matched and result['status'] != found:
+    print 'expected', found, 'got', result['status']
+    test.fail_test()
+  elif not matched and result['status'] != not_found:
+    print 'expected', not_found, 'got', result['status']
+    test.fail_test()
+
+
+def EnsureMatchedAll(targets):
+  result = _ReadOutputFileContents()
+  if result.get('error', None):
+    print 'unexpected error', result.get('error')
+    test.fail_test()
+
+  if result.get('warning', None):
+    print 'unexpected warning', result.get('warning')
+    test.fail_test()
+
+  if result['status'] != found_all:
+    print 'expected', found_all, 'got', result['status']
+    test.fail_test()
+
+  actual_targets = set(result['targets'])
+  if actual_targets != targets:
+    print 'actual targets:', actual_targets, '\nexpected targets:', targets
+    test.fail_test()
+
+
+def EnsureError(expected_error_string):
+  """Verifies output contains the error string."""
+  result = _ReadOutputFileContents()
+  if result.get('error', '').find(expected_error_string) == -1:
+    print 'actual error:', result.get('error', ''), '\nexpected error:', \
+        expected_error_string
+    test.fail_test()
+
+
+def EnsureStdoutContains(expected_error_string):
+  if test.stdout().find(expected_error_string) == -1:
+    print 'actual stdout:', test.stdout(), '\nexpected stdout:', \
+        expected_error_string
+    test.fail_test()
+
+
+def EnsureWarning(expected_warning_string):
+  """Verifies output contains the warning string."""
+  result = _ReadOutputFileContents()
+  if result.get('warning', '').find(expected_warning_string) == -1:
+    print 'actual warning:', result.get('warning', ''), \
+        '\nexpected warning:', expected_warning_string
+    test.fail_test()
+
+# Verifies config_path must be specified.
+test.run_gyp('test.gyp')
+EnsureStdoutContains('Must specify files to analyze via config_path')
+
+# Verifies config_path must point to a valid file.
+test.run_gyp('test.gyp', '-Gconfig_path=bogus_file',
+             '-Ganalyzer_output_path=analyzer_output')
+EnsureError('Unable to open file bogus_file')
+
+# Verify get warning when bad target is specified.
+_CreateConfigFile(['exe2.c'], ['bad_target'])
+run_analyzer()
+EnsureWarning('Unable to find all targets')
+
+# Verifies config_path must point to a valid json file.
+_CreateBogusConfigFile()
+run_analyzer()
+EnsureError('Unable to parse config file test_file')
 
 # Trivial test of a source.
-__CreateTestFile(['foo.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=found)
+_CreateConfigFile(['foo.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe'})
 
 # Conditional source that is excluded.
-__CreateTestFile(['conditional_source.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=not_found)
+_CreateConfigFile(['conditional_source.c'], [])
+run_analyzer()
+EnsureContains(matched=False)
 
 # Conditional source that is included by way of argument.
-__CreateTestFile(['conditional_source.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', '-Dtest_variable=1',
-             stdout=found)
+_CreateConfigFile(['conditional_source.c'], [])
+run_analyzer('-Dtest_variable=1')
+EnsureContains(matched=True, build_targets={'exe'})
 
 # Two unknown files.
-__CreateTestFile(['unknown1.c', 'unoknow2.cc'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=not_found)
+_CreateConfigFile(['unknown1.c', 'unoknow2.cc'], [])
+run_analyzer()
+EnsureContains()
 
 # Two unknown files.
-__CreateTestFile(['unknown1.c', 'subdir/subdir_sourcex.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=not_found)
+_CreateConfigFile(['unknown1.c', 'subdir/subdir_sourcex.c'], [])
+run_analyzer()
+EnsureContains()
 
 # Included dependency
-__CreateTestFile(['unknown1.c', 'subdir/subdir_source.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=found)
+_CreateConfigFile(['unknown1.c', 'subdir/subdir_source.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe', 'exe3'})
 
 # Included inputs to actions.
-__CreateTestFile(['action_input.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=found)
+_CreateConfigFile(['action_input.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe'})
 
 # Don't consider outputs.
-__CreateTestFile(['action_output.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=not_found)
+_CreateConfigFile(['action_output.c'], [])
+run_analyzer()
+EnsureContains(matched=False)
 
 # Rule inputs.
-__CreateTestFile(['rule_input.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=found)
+_CreateConfigFile(['rule_input.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe'})
 
-# Ignore patch specified with PRODUCT_DIR.
-__CreateTestFile(['product_dir_input.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=not_found)
+# Ignore path specified with PRODUCT_DIR.
+_CreateConfigFile(['product_dir_input.c'], [])
+run_analyzer()
+EnsureContains(matched=False)
 
 # Path specified via a variable.
-__CreateTestFile(['subdir/subdir_source2.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=found)
+_CreateConfigFile(['subdir/subdir_source2.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe'})
 
 # Verifies paths with // are fixed up correctly.
-__CreateTestFile(['parent_source.c'])
-test.run_gyp('test.gyp', '-Gfile_path=test_file', stdout=found)
+_CreateConfigFile(['parent_source.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe', 'exe3'})
+
+# Verifies relative paths are resolved correctly.
+_CreateConfigFile(['subdir/subdir_source.h'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe'})
+
+# Various permutations when passing in targets.
+_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe', 'exe3'])
+run_analyzer()
+EnsureContains(matched=True, targets={'exe3'}, build_targets={'exe2', 'exe3'})
+
+_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe'])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe2', 'exe3'})
+
+# Verifies duplicates are ignored.
+_CreateConfigFile(['exe2.c', 'subdir/subdir2b_source.c'], ['exe', 'exe'])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe2', 'exe3'})
+
+_CreateConfigFile(['exe2.c'], ['exe'])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe2'})
+
+_CreateConfigFile(['exe2.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe2'})
+
+_CreateConfigFile(['subdir/subdir2b_source.c', 'exe2.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe2', 'exe3'})
+
+_CreateConfigFile(['subdir/subdir2b_source.c'], ['exe3'])
+run_analyzer()
+EnsureContains(matched=True, targets={'exe3'}, build_targets={'exe3'})
+
+_CreateConfigFile(['exe2.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe2'})
+
+_CreateConfigFile(['foo.c'], [])
+run_analyzer()
+EnsureContains(matched=True, build_targets={'exe'})
+
+# Assertions when modifying build (gyp/gypi) files, especially when said files
+# are included.
+_CreateConfigFile(['subdir2/d.cc'], ['exe', 'exe2', 'foo', 'exe3'])
+run_analyzer2()
+EnsureContains(matched=True, targets={'exe', 'foo'}, build_targets={'exe'})
+
+_CreateConfigFile(['subdir2/subdir.includes.gypi'],
+                ['exe', 'exe2', 'foo', 'exe3'])
+run_analyzer2()
+EnsureContains(matched=True, targets={'exe', 'foo'}, build_targets={'exe'})
+
+_CreateConfigFile(['subdir2/subdir.gyp'], ['exe', 'exe2', 'foo', 'exe3'])
+run_analyzer2()
+EnsureContains(matched=True, targets={'exe', 'foo'}, build_targets={'exe'})
+
+_CreateConfigFile(['test2.includes.gypi'], ['exe', 'exe2', 'foo', 'exe3'])
+run_analyzer2()
+EnsureContains(matched=True, targets={'exe', 'exe2', 'exe3'},
+               build_targets={'exe', 'exe2', 'exe3'})
+
+# Verify modifying a file included makes all targets dirty.
+_CreateConfigFile(['common.gypi'], ['exe', 'exe2', 'foo', 'exe3'])
+run_analyzer2('-Icommon.gypi')
+EnsureMatchedAll({'exe', 'exe2', 'foo', 'exe3'})
+
+# Assertions from test3.gyp.
+_CreateConfigFile(['d.c', 'f.c'], ['a'])
+run_analyzer3()
+EnsureContains(matched=True, targets={'a'}, build_targets={'a', 'b'})
+
+_CreateConfigFile(['f.c'], ['a'])
+run_analyzer3()
+EnsureContains(matched=True, targets={'a'}, build_targets={'a', 'b'})
+
+_CreateConfigFile(['f.c'], [])
+run_analyzer3()
+EnsureContains(matched=True, build_targets={'a', 'b'})
+
+_CreateConfigFile(['c.c', 'e.c'], [])
+run_analyzer3()
+EnsureContains(matched=True, build_targets={'a', 'b', 'c', 'e'})
+
+_CreateConfigFile(['d.c'], ['a'])
+run_analyzer3()
+EnsureContains(matched=True, targets={'a'}, build_targets={'a', 'b'})
+
+_CreateConfigFile(['a.c'], ['a', 'b'])
+run_analyzer3()
+EnsureContains(matched=True, targets={'a'}, build_targets={'a'})
+
+_CreateConfigFile(['a.c'], ['a', 'b'])
+run_analyzer3()
+EnsureContains(matched=True, targets={'a'}, build_targets={'a'})
+
+_CreateConfigFile(['d.c'], ['a', 'b'])
+run_analyzer3()
+EnsureContains(matched=True, targets={'a', 'b'}, build_targets={'a', 'b'})
+
+_CreateConfigFile(['f.c'], ['a'])
+run_analyzer3()
+EnsureContains(matched=True, targets={'a'}, build_targets={'a', 'b'})
+
+_CreateConfigFile(['a.c'], ['a'])
+run_analyzer3()
+EnsureContains(matched=True, targets={'a'}, build_targets={'a'})
+
+_CreateConfigFile(['a.c'], [])
+run_analyzer3()
+EnsureContains(matched=True, build_targets={'a'})
+
+_CreateConfigFile(['d.c'], [])
+run_analyzer3()
+EnsureContains(matched=True, build_targets={'a', 'b'})
+
+# Assertions around test4.gyp.
+_CreateConfigFile(['f.c'], [])
+run_analyzer4()
+EnsureContains(matched=True, build_targets={'e', 'f'})
+
+_CreateConfigFile(['d.c'], [])
+run_analyzer4()
+EnsureContains(matched=True, build_targets={'a', 'b', 'c', 'd'})
+
+_CreateConfigFile(['i.c'], [])
+run_analyzer4()
+EnsureContains(matched=True, build_targets={'h'})
 
 test.pass_test()
diff --git a/test/analyzer/subdir/subdir.gyp b/test/analyzer/subdir/subdir.gyp
index cd0f013..bfa2df4 100644
--- a/test/analyzer/subdir/subdir.gyp
+++ b/test/analyzer/subdir/subdir.gyp
@@ -15,5 +15,22 @@
         '<(trailing_dir_path)/parent_source.c',
       ],
     },
+    {
+      'target_name': 'subdir2a',
+      'type': 'static_library',
+      'sources': [
+        'subdir2_source.c',
+      ],
+      'dependencies': [
+        'subdir2b',
+      ],
+    },
+    {
+      'target_name': 'subdir2b',
+      'type': 'static_library',
+      'sources': [
+        'subdir2b_source.c',
+      ],
+    },
   ],
 }
diff --git a/test/analyzer/subdir/subdir2/subdir2.gyp b/test/analyzer/subdir/subdir2/subdir2.gyp
new file mode 100644
index 0000000..e5aaa92
--- /dev/null
+++ b/test/analyzer/subdir/subdir2/subdir2.gyp
@@ -0,0 +1,15 @@
+# Copyright (c) 2014 Google Inc. 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': 'subdir2',
+      'type': 'static_library',
+      'sources': [
+        '../subdir_source.h',
+      ],
+    },
+  ],
+}
diff --git a/test/analyzer/subdir2/subdir.gyp b/test/analyzer/subdir2/subdir.gyp
new file mode 100644
index 0000000..d6c709c
--- /dev/null
+++ b/test/analyzer/subdir2/subdir.gyp
@@ -0,0 +1,18 @@
+# Copyright (c) 2014 Google Inc. 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': 'foo',
+      'type': 'static_library',
+      'sources': [
+        'subdir_source.c',
+      ],
+      'includes': [
+        'subdir.includes.gypi',
+      ],
+    },
+  ],
+}
diff --git a/test/analyzer/subdir2/subdir.includes.gypi b/test/analyzer/subdir2/subdir.includes.gypi
new file mode 100644
index 0000000..324e92b
--- /dev/null
+++ b/test/analyzer/subdir2/subdir.includes.gypi
@@ -0,0 +1,9 @@
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'sources': [
+    'd.cc'
+  ],
+}
diff --git a/test/analyzer/test.gyp b/test/analyzer/test.gyp
index b3fcdd3..a5201cb 100644
--- a/test/analyzer/test.gyp
+++ b/test/analyzer/test.gyp
@@ -2,6 +2,36 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# These gyp files create the following dependencies:
+#
+# test.gyp:
+#   #exe -> subdir/subdir.gyp#foo, subdir/subdir2/subdir2.gyp#subdir2
+#     foo.c
+#     subdir/subdir_source2.c
+#     conditional_source.c (if test_variable==1)
+#     action_input.c
+#     action_output.c
+#     rule_input.c
+#     rule_output.pdf
+#   #exe2
+#     exe2.c
+#   #exe3 -> subdir/subdir.gyp#foo, subdir/subdir.gyp#subdir2a
+#     exe3.c
+#   #all (type none) -> exe, exe3
+# 
+# subdir/subdir.gyp
+#   #foo
+#     subdir/subdir_source.c
+#     parent_source.c
+#   #subdir2a -> subdir2b
+#     subdir/subdir2_source.c
+#   #subdir2b
+#     subdir/subdir2b_source.c
+# 
+# subdir/subdir2/subdir2.gyp
+#   #subdir2
+#     subdir/subdir_source.h
+
 {
   'variables': {
     'test_variable%': 0,
@@ -13,6 +43,7 @@
       'type': 'executable',
       'dependencies': [
         'subdir/subdir.gyp:foo',
+        'subdir/subdir2/subdir2.gyp:subdir2',
       ],
       'sources': [
         'foo.c',
@@ -31,6 +62,8 @@
           'inputs': [
             '<(PRODUCT_DIR)/product_dir_input.c',
             'action_input.c',
+            '../bad_path1.h',
+            '../../bad_path2.h',
           ],
           'outputs': [
             'action_output.c',
@@ -50,5 +83,31 @@
         },
       ],
     },
+    {
+      'target_name': 'exe2',
+      'type': 'executable',
+      'sources': [
+        'exe2.c',
+      ],
+    },
+    {
+      'target_name': 'exe3',
+      'type': 'executable',
+      'dependencies': [
+        'subdir/subdir.gyp:foo',
+        'subdir/subdir.gyp:subdir2a',
+      ],
+      'sources': [
+        'exe3.c',
+      ],
+    },
+    {
+      'target_name': 'all',
+      'type': 'none',
+      'dependencies': [
+        'exe',
+        'exe3',
+      ],
+    },
   ],
 }
diff --git a/test/analyzer/test2.gyp b/test/analyzer/test2.gyp
new file mode 100644
index 0000000..782b6e6
--- /dev/null
+++ b/test/analyzer/test2.gyp
@@ -0,0 +1,25 @@
+# Copyright (c) 2014 Google Inc. 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': 'exe',
+      'type': 'executable',
+      'dependencies': [
+        'subdir2/subdir.gyp:foo',
+      ],
+    },
+    {
+      'target_name': 'exe2',
+      'type': 'executable',
+      'includes': [
+        'test2.includes.gypi',
+      ],
+    },
+  ],
+  'includes': [
+    'test2.toplevel_includes.gypi',
+  ],
+}
diff --git a/test/analyzer/test2.includes.gypi b/test/analyzer/test2.includes.gypi
new file mode 100644
index 0000000..3e21de2
--- /dev/null
+++ b/test/analyzer/test2.includes.gypi
@@ -0,0 +1,13 @@
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'sources': [
+    'a.cc',
+    'b.cc'
+  ],
+  'includes': [
+    'test2.includes.includes.gypi',
+  ],
+}
diff --git a/test/analyzer/test2.includes.includes.gypi b/test/analyzer/test2.includes.includes.gypi
new file mode 100644
index 0000000..de3a025
--- /dev/null
+++ b/test/analyzer/test2.includes.includes.gypi
@@ -0,0 +1,9 @@
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'sources': [
+    'c.cc'
+  ],
+}
diff --git a/test/analyzer/test2.toplevel_includes.gypi b/test/analyzer/test2.toplevel_includes.gypi
new file mode 100644
index 0000000..54fa453
--- /dev/null
+++ b/test/analyzer/test2.toplevel_includes.gypi
@@ -0,0 +1,15 @@
+# Copyright (c) 2014 Google Inc. 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': 'exe3',
+      'type': 'executable',
+      'sources': [
+        'e.cc',
+      ],
+    },
+  ],
+}
diff --git a/test/analyzer/test3.gyp b/test/analyzer/test3.gyp
new file mode 100644
index 0000000..40c7534
--- /dev/null
+++ b/test/analyzer/test3.gyp
@@ -0,0 +1,77 @@
+# Copyright (c) 2014 Google Inc. 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': 'all',
+      'type': 'none',
+      'dependencies': [
+        'a',
+        'b',
+      ],
+    },
+    {
+      'target_name': 'a',
+      'type': 'executable',
+      'sources': [
+        'a.c',
+      ],
+      'dependencies': [
+        'c',
+        'd',
+      ],
+    },
+    {
+      'target_name': 'b',
+      'type': 'executable',
+      'sources': [
+        'b.c',
+      ],
+      'dependencies': [
+        'd',
+        'e',
+      ],
+    },
+    {
+      'target_name': 'c',
+      'type': 'executable',
+      'sources': [
+        'c.c',
+      ],
+    },
+    {
+      'target_name': 'd',
+      'type': 'none',
+      'sources': [
+        'd.c',
+      ],
+      'dependencies': [
+        'f',
+        'g',
+      ],
+    },
+    {
+      'target_name': 'e',
+      'type': 'executable',
+      'sources': [
+        'e.c',
+      ],
+    },
+    {
+      'target_name': 'f',
+      'type': 'static_library',
+      'sources': [
+        'f.c',
+      ],
+    },
+    {
+      'target_name': 'g',
+      'type': 'executable',
+      'sources': [
+        'g.c',
+      ],
+    },
+  ],
+}
diff --git a/test/analyzer/test4.gyp b/test/analyzer/test4.gyp
new file mode 100644
index 0000000..91cea56
--- /dev/null
+++ b/test/analyzer/test4.gyp
@@ -0,0 +1,80 @@
+# Copyright (c) 2014 Google Inc. 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': 'a',
+      'type': 'executable',
+      'sources': [
+        'a.c',
+      ],
+      'dependencies': [
+        'b',
+        'c',
+      ],
+    },
+    {
+      'target_name': 'b',
+      'type': 'executable',
+      'sources': [
+        'b.c',
+      ],
+      'dependencies': [
+        'd',
+      ],
+    },
+    {
+      'target_name': 'c',
+      'type': 'executable',
+      'sources': [
+        'c.c',
+      ],
+      'dependencies': [
+        'b',
+        'd',
+      ],
+    },
+    {
+      'target_name': 'd',
+      'type': 'executable',
+      'sources': [
+        'd.c',
+      ],
+    },
+    {
+      'target_name': 'e',
+      'type': 'executable',
+      'dependencies': [
+        'test5.gyp:f',
+      ],
+    },
+    {
+      'target_name': 'h',
+      'type': 'none',
+      'dependencies': [
+        'i',
+      ],
+      'rules': [
+        {
+          'rule_name': 'rule',
+          'extension': 'pdf',
+          'inputs': [
+            'rule_input.c',
+          ],
+          'outputs': [
+            'rule_output.pdf',
+          ],
+        },
+      ],
+    },
+    {
+      'target_name': 'i',
+      'type': 'static_library',
+      'sources': [
+        'i.c',
+      ],
+    },
+  ],
+}
diff --git a/test/analyzer/test5.gyp b/test/analyzer/test5.gyp
new file mode 100644
index 0000000..f3ea5b0
--- /dev/null
+++ b/test/analyzer/test5.gyp
@@ -0,0 +1,25 @@
+# Copyright (c) 2014 Google Inc. 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': 'f',
+      'type': 'executable',
+      'sources': [
+        'f.c',
+      ],
+    },
+    {
+      'target_name': 'g',
+      'type': 'executable',
+      'sources': [
+        'g.c',
+      ],
+      'dependencies': [
+        'f',
+      ],
+    },
+  ],
+}
diff --git a/test/android/32or64.c b/test/android/32or64.c
new file mode 100644
index 0000000..3ea8169
--- /dev/null
+++ b/test/android/32or64.c
@@ -0,0 +1,13 @@
+/* Copyright (c) 2014 Google Inc. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+const char* getString()
+{
+#ifdef __LP64__
+  return "Hello, 64-bit world!\n";
+#else
+  return "Hello, 32-bit world!\n";
+#endif
+}
diff --git a/test/android/gyptest-host-multilib.py b/test/android/gyptest-host-multilib.py
new file mode 100755
index 0000000..4fb7919
--- /dev/null
+++ b/test/android/gyptest-host-multilib.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies that it's possible to build host targets correctly in a multilib
+configuration, explicitly forcing either 32 or 64 bit.
+"""
+
+import TestGyp
+
+test = TestGyp.TestGyp(formats=['android'])
+
+test.run_gyp('host_32or64.gyp')
+
+# Force building as 32-bit
+test.build('host_32or64.gyp', 'generate_output',
+           arguments=['GYP_HOST_VAR_PREFIX=$(HOST_2ND_ARCH_VAR_PREFIX)',
+                      'GYP_HOST_MULTILIB=32'])
+
+test.built_file_must_match('host_32or64.output', 'Hello, 32-bit world!\n')
+
+# Force building as 64-bit
+test.build('host_32or64.gyp', 'generate_output',
+           arguments=['GYP_HOST_VAR_PREFIX=',
+                      'GYP_HOST_MULTILIB=64'])
+
+test.built_file_must_match('host_32or64.output', 'Hello, 64-bit world!\n')
+
+test.pass_test()
diff --git a/test/android/gyptest-settings-list.py b/test/android/gyptest-settings-list.py
new file mode 100755
index 0000000..5850d47
--- /dev/null
+++ b/test/android/gyptest-settings-list.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies that it's possible to set Android build system settings using the
+aosp_build_settings key, with list values.
+"""
+
+import TestGyp
+
+test = TestGyp.TestGyp(formats=['android'])
+
+test.run_gyp('settings-list.gyp')
+
+test.build('settings-list.gyp', 'hello')
+
+test.run_built_executable('hello.foo', stdout="Hello, world!\n")
+
+test.up_to_date('settings-list.gyp', test.DEFAULT)
+
+test.pass_test()
diff --git a/test/android/gyptest-settings.py b/test/android/gyptest-settings.py
new file mode 100755
index 0000000..f4e89d1
--- /dev/null
+++ b/test/android/gyptest-settings.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies that it's possible to set Android build system settings using the
+aosp_build_settings key.
+"""
+
+import TestGyp
+
+test = TestGyp.TestGyp(formats=['android'])
+
+test.run_gyp('settings.gyp')
+
+test.build('settings.gyp', 'hello')
+
+test.run_built_executable('hello.foo', stdout="Hello, world!\n")
+
+test.up_to_date('settings.gyp', test.DEFAULT)
+
+test.pass_test()
diff --git a/test/android/host_32or64.gyp b/test/android/host_32or64.gyp
new file mode 100644
index 0000000..e8ca79f
--- /dev/null
+++ b/test/android/host_32or64.gyp
@@ -0,0 +1,38 @@
+# Copyright (c) 2014 Google Inc. 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': 'lib32or64',
+      'type': 'static_library',
+      'toolsets': [ 'host' ],
+      'sources': [
+        '32or64.c',
+      ],
+    },
+    {
+      'target_name': 'host_32or64',
+      'type': 'executable',
+      'toolsets': [ 'host' ],
+      'dependencies': [ 'lib32or64#host' ],
+      'sources': [
+        'writefile.c',
+      ],
+    },
+    {
+      'target_name': 'generate_output',
+      'type': 'none',
+      'dependencies': [ 'host_32or64#host' ],
+      'actions': [
+        {
+          'action_name': 'generate',
+          'inputs': [ '<(PRODUCT_DIR)/host_32or64' ],
+          'outputs': [ '<(PRODUCT_DIR)/host_32or64.output' ],
+          'action': [ '<@(_inputs)', '<@(_outputs)' ],
+        }
+      ],
+    },
+  ],
+}
diff --git a/test/android/settings-list.gyp b/test/android/settings-list.gyp
new file mode 100644
index 0000000..b392ce2
--- /dev/null
+++ b/test/android/settings-list.gyp
@@ -0,0 +1,18 @@
+# Copyright (c) 2014 Google Inc. 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': 'hello',
+      'type': 'executable',
+      'sources': [
+        'hello.c',
+      ],
+      'aosp_build_settings': {
+        'LOCAL_MODULE_SUFFIX': ['.foo'],
+      }
+    },
+  ],
+}
diff --git a/test/android/settings.gyp b/test/android/settings.gyp
new file mode 100644
index 0000000..2f8ce7f
--- /dev/null
+++ b/test/android/settings.gyp
@@ -0,0 +1,18 @@
+# Copyright (c) 2014 Google Inc. 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': 'hello',
+      'type': 'executable',
+      'sources': [
+        'hello.c',
+      ],
+      'aosp_build_settings': {
+        'LOCAL_MODULE_SUFFIX': '.foo',
+      }
+    },
+  ],
+}
diff --git a/test/android/writefile.c b/test/android/writefile.c
new file mode 100644
index 0000000..3f5960f
--- /dev/null
+++ b/test/android/writefile.c
@@ -0,0 +1,18 @@
+/* Copyright (c) 2014 Google Inc. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <stdio.h>
+
+extern const char* getString(void);
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) return 2;
+  FILE* f = fopen(argv[1], "w");
+  if (f == NULL) return 1;
+  fprintf(f, "%s", getString());
+  fclose(f);
+  return 0;
+}
diff --git a/test/compiler-override/compiler.gyp b/test/compiler-override/compiler-exe.gyp
similarity index 100%
rename from test/compiler-override/compiler.gyp
rename to test/compiler-override/compiler-exe.gyp
diff --git a/test/compiler-override/compiler-shared-lib.gyp b/test/compiler-override/compiler-shared-lib.gyp
new file mode 100644
index 0000000..d3e4316
--- /dev/null
+++ b/test/compiler-override/compiler-shared-lib.gyp
@@ -0,0 +1,16 @@
+# Copyright (c) 2012 Google Inc. 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': 'hello-lib',
+      'type': 'shared_library',
+      'sources': [
+        'test.c',
+        'cxxtest.cc',
+      ],
+    },
+  ],
+}
diff --git a/test/compiler-override/gyptest-compiler-env-toolchain.py b/test/compiler-override/gyptest-compiler-env-toolchain.py
new file mode 100644
index 0000000..c27be24
--- /dev/null
+++ b/test/compiler-override/gyptest-compiler-env-toolchain.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""
+Verifies that the user can override the compiler and linker using
+CC/CXX/NM/READELF environment variables.
+"""
+
+import TestGyp
+import os
+import copy
+import sys
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+if sys.platform == 'win32':
+  # cross compiling not supported by ninja on windows
+  # and make not supported on windows at all.
+  sys.exit(0)
+
+# Clear any existing compiler related env vars.
+for key in ['CC', 'CXX', 'LINK', 'CC_host', 'CXX_host', 'LINK_host',
+            'NM_target', 'READELF_target']:
+  if key in os.environ:
+    del os.environ[key]
+
+
+def CheckCompiler(test, gypfile, check_for, run_gyp):
+  if run_gyp:
+    test.run_gyp(gypfile)
+  test.build(gypfile)
+
+  test.must_contain_all_lines(test.stdout(), check_for)
+
+
+test = TestGyp.TestGyp(formats=['ninja'])
+# Must set the test format to something with a flavor (the part after the '-')
+# in order to test the desired behavior. Since we want to run a non-host
+# toolchain, we have to set the flavor to something that the ninja generator
+# doesn't know about, so it doesn't default to the host-specific tools (e.g.,
+# 'otool' on mac to generate the .TOC).
+#
+# Note that we can't just pass format=['ninja-some_toolchain'] to the
+# constructor above, because then this test wouldn't be recognized as a ninja
+# format test.
+test.formats = ['ninja-some_flavor']
+
+
+def TestTargetOverideSharedLib():
+  # The std output from nm and readelf is redirected to files, so we can't
+  # expect their output to appear. Instead, check for the files they create to
+  # see if they actually ran.
+  expected = ['my_cc.py', 'my_cxx.py', 'FOO']
+
+  # Check that CC, CXX, NM, READELF, set target compiler
+  env = {'CC': 'python %s/my_cc.py FOO' % here,
+         'CXX': 'python %s/my_cxx.py FOO' % here,
+         'NM': 'python %s/my_nm.py' % here,
+         'READELF': 'python %s/my_readelf.py' % here}
+
+  with TestGyp.LocalEnv(env):
+    CheckCompiler(test, 'compiler-shared-lib.gyp', expected, True)
+    test.must_contain(test.built_file_path('RAN_MY_NM'), 'RAN_MY_NM')
+    test.must_contain(test.built_file_path('RAN_MY_READELF'), 'RAN_MY_READELF')
+    test.unlink(test.built_file_path('RAN_MY_NM'))
+    test.unlink(test.built_file_path('RAN_MY_READELF'))
+
+  # Run the same tests once the eviron has been restored.  The generated
+  # projects should have embedded all the settings in the project files so the
+  # results should be the same.
+  CheckCompiler(test, 'compiler-shared-lib.gyp', expected, False)
+  test.must_contain(test.built_file_path('RAN_MY_NM'), 'RAN_MY_NM')
+  test.must_contain(test.built_file_path('RAN_MY_READELF'), 'RAN_MY_READELF')
+
+
+TestTargetOverideSharedLib()
+test.pass_test()
diff --git a/test/compiler-override/gyptest-compiler-env.py b/test/compiler-override/gyptest-compiler-env.py
index d13d692..6408ae1 100755
--- a/test/compiler-override/gyptest-compiler-env.py
+++ b/test/compiler-override/gyptest-compiler-env.py
@@ -15,7 +15,7 @@
 here = os.path.dirname(os.path.abspath(__file__))
 
 if sys.platform == 'win32':
-  # cross compiling not support by ninja on windows
+  # cross compiling not supported by ninja on windows
   # and make not supported on windows at all.
   sys.exit(0)
 
@@ -30,8 +30,6 @@
     test.run_gyp(gypfile)
   test.build(gypfile)
 
-  # We can't test to presence of my_ld.py in the output since
-  # ninja will use CXX_target as the linker regardless
   test.must_contain_all_lines(test.stdout(), check_for)
 
 
@@ -49,8 +47,7 @@
     os.environ['CXX'] = 'python %s/my_cxx.py FOO' % here
     os.environ['LINK'] = 'python %s/my_ld.py FOO_LINK' % here
 
-    CheckCompiler(test, 'compiler.gyp', expected,
-                  True)
+    CheckCompiler(test, 'compiler-exe.gyp', expected, True)
   finally:
     os.environ.clear()
     os.environ.update(oldenv)
@@ -58,8 +55,8 @@
   # Run the same tests once the eviron has been restored.  The
   # generated should have embedded all the settings in the
   # project files so the results should be the same.
-  CheckCompiler(test, 'compiler.gyp', expected,
-                False)
+  CheckCompiler(test, 'compiler-exe.gyp', expected, False)
+
 
 def TestTargetOverideCompilerOnly():
   # Same test again but with that CC, CXX and not LD
@@ -68,7 +65,7 @@
     os.environ['CC'] = 'python %s/my_cc.py FOO' % here
     os.environ['CXX'] = 'python %s/my_cxx.py FOO' % here
 
-    CheckCompiler(test, 'compiler.gyp',
+    CheckCompiler(test, 'compiler-exe.gyp',
                   ['my_cc.py', 'my_cxx.py', 'FOO'],
                   True)
   finally:
@@ -78,7 +75,7 @@
   # Run the same tests once the eviron has been restored.  The
   # generated should have embedded all the settings in the
   # project files so the results should be the same.
-  CheckCompiler(test, 'compiler.gyp',
+  CheckCompiler(test, 'compiler-exe.gyp',
                 ['my_cc.py', 'my_cxx.py', 'FOO'],
                 False)
 
diff --git a/test/compiler-override/my_nm.py b/test/compiler-override/my_nm.py
new file mode 100755
index 0000000..f0f1efc
--- /dev/null
+++ b/test/compiler-override/my_nm.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import sys
+print sys.argv
+with open('RAN_MY_NM', 'w') as f:
+  f.write('RAN_MY_NM')
diff --git a/test/compiler-override/my_readelf.py b/test/compiler-override/my_readelf.py
new file mode 100755
index 0000000..40e303c
--- /dev/null
+++ b/test/compiler-override/my_readelf.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import sys
+print sys.argv
+with open('RAN_MY_READELF', 'w') as f:
+  f.write('RAN_MY_READELF')
diff --git a/test/empty-target/empty-target.gyp b/test/empty-target/empty-target.gyp
new file mode 100644
index 0000000..feefa28
--- /dev/null
+++ b/test/empty-target/empty-target.gyp
@@ -0,0 +1,12 @@
+# Copyright (c) 2014 Google Inc. 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': 'empty_target',
+      'type': 'none',
+    },
+  ],
+}
diff --git a/test/empty-target/gyptest-empty-target.py b/test/empty-target/gyptest-empty-target.py
new file mode 100644
index 0000000..ecadd4a
--- /dev/null
+++ b/test/empty-target/gyptest-empty-target.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies building a target with nothing succeeds.
+"""
+
+import os
+import sys
+import TestGyp
+
+test = TestGyp.TestGyp()
+test.run_gyp('empty-target.gyp')
+test.build('empty-target.gyp', target='empty_target')
+test.pass_test()
diff --git a/test/errors/gyptest-errors.py b/test/errors/gyptest-errors.py
index 446607f..5f66bac 100755
--- a/test/errors/gyptest-errors.py
+++ b/test/errors/gyptest-errors.py
@@ -8,6 +8,9 @@
 Test that two targets with the same name generates an error.
 """
 
+import os
+import sys
+
 import TestGyp
 import TestCmd
 
@@ -39,6 +42,16 @@
 stderr = 'gyp: Duplicate basenames in sources section, see list above\n'
 test.run_gyp('duplicate_basenames.gyp', status=1, stderr=stderr)
 
+# Check if '--no-duplicate-basename-check' works.
+if ((test.format == 'make' and sys.platform == 'darwin') or
+    (test.format == 'msvs' and
+        int(os.environ.get('GYP_MSVS_VERSION', 2010)) < 2010)):
+  stderr = 'gyp: Duplicate basenames in sources section, see list above\n'
+  test.run_gyp('duplicate_basenames.gyp', '--no-duplicate-basename-check',
+               status=1, stderr=stderr)
+else:
+  test.run_gyp('duplicate_basenames.gyp', '--no-duplicate-basename-check')
+
 stderr = ("gyp: Dependency '.*missing_dep.gyp:missing.gyp#target' not found "
           "while trying to load target .*missing_dep.gyp:foo#target\n")
 test.run_gyp('missing_dep.gyp', status=1, stderr=stderr,
diff --git a/test/generator-output/gyptest-actions.py b/test/generator-output/gyptest-actions.py
index 2bd09c8..8c912e4 100755
--- a/test/generator-output/gyptest-actions.py
+++ b/test/generator-output/gyptest-actions.py
@@ -18,6 +18,7 @@
 test.writable(test.workpath('actions'), False)
 test.run_gyp('actions.gyp',
              '--generator-output=' + test.workpath('gypfiles'),
+             '-G', 'xcode_ninja_target_pattern=^pull_in_all_actions$',
              chdir='actions')
 
 test.writable(test.workpath('actions'), True)
diff --git a/test/generator-output/gyptest-copies.py b/test/generator-output/gyptest-copies.py
index 7524b17..909aebf 100755
--- a/test/generator-output/gyptest-copies.py
+++ b/test/generator-output/gyptest-copies.py
@@ -18,6 +18,7 @@
 
 test.run_gyp('copies.gyp',
              '--generator-output=' + test.workpath('gypfiles'),
+             '-G', 'xcode_ninja_target_pattern=^(?!copies_null)',
              chdir='copies')
 
 test.writable(test.workpath('copies'), True)
@@ -39,7 +40,7 @@
 
 if test.format == 'xcode':
   chdir = 'relocate/copies/build'
-elif test.format in ['make', 'ninja', 'cmake']:
+elif test.format in ['make', 'ninja', 'xcode-ninja', 'cmake']:
   chdir = 'relocate/gypfiles/out'
 else:
   chdir = 'relocate/gypfiles'
@@ -50,7 +51,7 @@
 
 if test.format == 'xcode':
   chdir = 'relocate/copies/subdir/build'
-elif test.format in ['make', 'ninja', 'cmake']:
+elif test.format in ['make', 'ninja', 'xcode-ninja', 'cmake']:
   chdir = 'relocate/gypfiles/out'
 else:
   chdir = 'relocate/gypfiles'
diff --git a/test/generator-output/gyptest-rules.py b/test/generator-output/gyptest-rules.py
index 324d5c2..b95e005 100755
--- a/test/generator-output/gyptest-rules.py
+++ b/test/generator-output/gyptest-rules.py
@@ -17,6 +17,7 @@
 
 test.run_gyp('rules.gyp',
              '--generator-output=' + test.workpath('gypfiles'),
+             '-G', 'xcode_ninja_target_pattern=^pull_in_all_actions$',
              chdir='rules')
 
 test.writable(test.workpath('rules'), True)
diff --git a/test/ios/extension/ActionExtension/ActionViewController.h b/test/ios/extension/ActionExtension/ActionViewController.h
new file mode 100644
index 0000000..1c92509
--- /dev/null
+++ b/test/ios/extension/ActionExtension/ActionViewController.h
@@ -0,0 +1,9 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <UIKit/UIKit.h>
+
+@interface ActionViewController : UIViewController
+
+@end
diff --git a/test/ios/extension/ActionExtension/ActionViewController.m b/test/ios/extension/ActionExtension/ActionViewController.m
new file mode 100644
index 0000000..d37bacd
--- /dev/null
+++ b/test/ios/extension/ActionExtension/ActionViewController.m
@@ -0,0 +1,31 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ActionViewController.h"
+#import <MobileCoreServices/MobileCoreServices.h>
+
+@interface ActionViewController ()
+
+@end
+
+@implementation ActionViewController
+
+- (void)viewDidLoad {
+  [super viewDidLoad];
+}
+
+- (void)didReceiveMemoryWarning {
+  [super didReceiveMemoryWarning];
+  // Dispose of any resources that can be recreated.
+}
+
+- (IBAction)done {
+  // Return any edited content to the host app.
+  // This template doesn't do anything, so we just echo the passed in items.
+  [self.extensionContext
+      completeRequestReturningItems:self.extensionContext.inputItems
+      completionHandler:nil];
+}
+
+@end
diff --git a/test/ios/extension/ActionExtension/Info.plist b/test/ios/extension/ActionExtension/Info.plist
new file mode 100644
index 0000000..f89cd79
--- /dev/null
+++ b/test/ios/extension/ActionExtension/Info.plist
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleDisplayName</key>
+	<string>ActionExtension</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.google.gyptest.extension.ActionExtension</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>XPC!</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>NSExtension</key>
+	<dict>
+		<key>NSExtensionAttributes</key>
+		<dict>
+			<key>NSExtensionActivationRule</key>
+			<string>TRUEPREDICATE</string>
+			<key>NSExtensionPointName</key>
+			<string>com.apple.ui-services</string>
+			<key>NSExtensionPointVersion</key>
+			<string>1.0</string>
+		</dict>
+		<key>NSExtensionMainStoryboard</key>
+		<string>MainInterface</string>
+		<key>NSExtensionPointIdentifier</key>
+		<string>com.apple.ui-services</string>
+	</dict>
+</dict>
+</plist>
diff --git a/test/ios/extension/ActionExtension/MainInterface.storyboard b/test/ios/extension/ActionExtension/MainInterface.storyboard
new file mode 100644
index 0000000..5aa5818
--- /dev/null
+++ b/test/ios/extension/ActionExtension/MainInterface.storyboard
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6148" systemVersion="14A229a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="ObA-dk-sSI">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6147"/>
+    </dependencies>
+    <scenes>
+        <!--Action View Controller - Image-->
+        <scene sceneID="7MM-of-jgj">
+            <objects>
+                <viewController title="Image" id="ObA-dk-sSI" customClass="ActionViewController" customModuleProvider="" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="qkL-Od-lgU"/>
+                        <viewControllerLayoutGuide type="bottom" id="n38-gi-rB5"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="zMn-AG-sqS">
+                        <rect key="frame" x="0.0" y="0.0" width="320" height="528"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="9ga-4F-77Z">
+                                <rect key="frame" x="0.0" y="64" width="320" height="464"/>
+                            </imageView>
+                            <navigationBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NOA-Dm-cuz">
+                                <rect key="frame" x="0.0" y="20" width="320" height="44"/>
+                                <items>
+                                    <navigationItem id="3HJ-uW-3hn">
+                                        <barButtonItem key="leftBarButtonItem" title="Done" style="done" id="WYi-yp-eM6">
+                                            <connections>
+                                                <action selector="done" destination="ObA-dk-sSI" id="Qdu-qn-U6V"/>
+                                            </connections>
+                                        </barButtonItem>
+                                    </navigationItem>
+                                </items>
+                            </navigationBar>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstAttribute="trailing" secondItem="NOA-Dm-cuz" secondAttribute="trailing" id="A05-Pj-hrr"/>
+                            <constraint firstItem="9ga-4F-77Z" firstAttribute="top" secondItem="NOA-Dm-cuz" secondAttribute="bottom" id="Fps-3D-QQW"/>
+                            <constraint firstItem="NOA-Dm-cuz" firstAttribute="leading" secondItem="zMn-AG-sqS" secondAttribute="leading" id="HxO-8t-aoh"/>
+                            <constraint firstAttribute="trailing" secondItem="9ga-4F-77Z" secondAttribute="trailing" id="Ozw-Hg-0yh"/>
+                            <constraint firstItem="9ga-4F-77Z" firstAttribute="leading" secondItem="zMn-AG-sqS" secondAttribute="leading" id="XH5-ld-ONA"/>
+                            <constraint firstItem="n38-gi-rB5" firstAttribute="top" secondItem="9ga-4F-77Z" secondAttribute="bottom" id="eQg-nn-Zy4"/>
+                            <constraint firstItem="NOA-Dm-cuz" firstAttribute="top" secondItem="qkL-Od-lgU" secondAttribute="bottom" id="we0-1t-bgp"/>
+                        </constraints>
+                    </view>
+                    <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+                    <size key="freeformSize" width="320" height="528"/>
+                    <connections>
+                        <outlet property="imageView" destination="9ga-4F-77Z" id="5y6-5w-9QO"/>
+                        <outlet property="view" destination="zMn-AG-sqS" id="Qma-de-2ek"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="X47-rx-isc" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="252" y="-124"/>
+        </scene>
+    </scenes>
+    <simulatedMetricsContainer key="defaultSimulatedMetrics">
+        <simulatedStatusBarMetrics key="statusBar"/>
+        <simulatedOrientationMetrics key="orientation"/>
+        <simulatedScreenMetrics key="destination" type="retina4"/>
+    </simulatedMetricsContainer>
+</document>
diff --git a/test/ios/extension/ExtensionContainer/AppDelegate.h b/test/ios/extension/ExtensionContainer/AppDelegate.h
new file mode 100644
index 0000000..510e230
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/AppDelegate.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end
+
diff --git a/test/ios/extension/ExtensionContainer/AppDelegate.m b/test/ios/extension/ExtensionContainer/AppDelegate.m
new file mode 100644
index 0000000..1197bc1
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/AppDelegate.m
@@ -0,0 +1,19 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication*)application
+    didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
+  // Override point for customization after application launch.
+  return YES;
+}
+
+@end
diff --git a/test/ios/extension/ExtensionContainer/Base.lproj/Main.storyboard b/test/ios/extension/ExtensionContainer/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..e8f3cfb
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/Base.lproj/Main.storyboard
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6162" systemVersion="14A238h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6160"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="tne-QT-ifu">
+            <objects>
+                <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+                        <rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+    </scenes>
+</document>
diff --git a/test/ios/extension/ExtensionContainer/Images.xcassets/AppIcon.appiconset/Contents.json b/test/ios/extension/ExtensionContainer/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..f697f61
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,53 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
diff --git a/test/ios/extension/ExtensionContainer/Images.xcassets/LaunchImage.launchimage/Contents.json b/test/ios/extension/ExtensionContainer/Images.xcassets/LaunchImage.launchimage/Contents.json
new file mode 100644
index 0000000..4458b40
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/Images.xcassets/LaunchImage.launchimage/Contents.json
@@ -0,0 +1,51 @@
+{
+  "images" : [
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "subtype" : "retina4",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
diff --git a/test/ios/extension/ExtensionContainer/Info.plist b/test/ios/extension/ExtensionContainer/Info.plist
new file mode 100644
index 0000000..31ccf4c
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>CFBundleDevelopmentRegion</key>
+    <string>en</string>
+    <key>CFBundleExecutable</key>
+    <string>ExtensionContainer</string>
+    <key>CFBundleIdentifier</key>
+    <string>com.google.gyptest.extension</string>
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+    <key>CFBundleName</key>
+    <string>${PRODUCT_NAME}</string>
+    <key>CFBundlePackageType</key>
+    <string>APPL</string>
+    <key>CFBundleShortVersionString</key>
+    <string>1.0</string>
+    <key>CFBundleSignature</key>
+    <string>????</string>
+    <key>CFBundleVersion</key>
+    <string>1</string>
+    <key>LSRequiresIPhoneOS</key>
+    <true/>
+    <key>UIMainStoryboardFile</key>
+    <string>Main</string>
+    <key>UIRequiredDeviceCapabilities</key>
+    <array>
+        <string>armv7</string>
+    </array>
+</dict>
+</plist>
diff --git a/test/ios/extension/ExtensionContainer/ViewController.h b/test/ios/extension/ExtensionContainer/ViewController.h
new file mode 100644
index 0000000..fad7754
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/ViewController.h
@@ -0,0 +1,11 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <UIKit/UIKit.h>
+
+@interface ViewController : UIViewController
+
+
+@end
+
diff --git a/test/ios/extension/ExtensionContainer/ViewController.m b/test/ios/extension/ExtensionContainer/ViewController.m
new file mode 100644
index 0000000..3810fa9
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/ViewController.m
@@ -0,0 +1,24 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ViewController.h"
+
+@interface ViewController ()
+
+
+@end
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+  [super viewDidLoad];
+  // Do any additional setup after loading the view, typically from a nib.
+}
+
+- (void)didReceiveMemoryWarning {
+  [super didReceiveMemoryWarning];
+  // Dispose of any resources that can be recreated.
+}
+
+@end
diff --git a/test/ios/extension/ExtensionContainer/main.m b/test/ios/extension/ExtensionContainer/main.m
new file mode 100644
index 0000000..47aecb5
--- /dev/null
+++ b/test/ios/extension/ExtensionContainer/main.m
@@ -0,0 +1,13 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char* argv[]) {
+  @autoreleasepool {
+    return UIApplicationMain(argc, argv, nil,
+        NSStringFromClass([AppDelegate class]));
+  }
+}
diff --git a/test/ios/extension/extension.gyp b/test/ios/extension/extension.gyp
new file mode 100644
index 0000000..6fa468c
--- /dev/null
+++ b/test/ios/extension/extension.gyp
@@ -0,0 +1,83 @@
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'make_global_settings': [
+    ['CC', '/usr/bin/clang'],
+    ['CXX', '/usr/bin/clang++'],
+  ],
+  'targets': [
+    {
+      'target_name': 'ExtensionContainer',
+      'product_name': 'ExtensionContainer',
+      'type': 'executable',
+      'mac_bundle': 1,
+      'mac_bundle_resources': [
+        'ExtensionContainer/Base.lproj/Main.storyboard',
+      ],
+      'sources': [
+        'ExtensionContainer/AppDelegate.h',
+        'ExtensionContainer/AppDelegate.m',
+        'ExtensionContainer/ViewController.h',
+        'ExtensionContainer/ViewController.m',
+        'ExtensionContainer/main.m',
+      ],
+      'copies': [
+        {
+          'destination': '<(PRODUCT_DIR)/ExtensionContainer.app/PlugIns',
+          'files': [
+            '<(PRODUCT_DIR)/ActionExtension.appex',
+      ]}],
+      'dependencies': [
+        'ActionExtension'
+      ],
+
+      'link_settings': {
+        'libraries': [
+          '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+          '$(SDKROOT)/System/Library/Frameworks/UIKit.framework',
+        ],
+      },
+      'xcode_settings': {
+        'OTHER_CFLAGS': [
+          '-fobjc-abi-version=2',
+        ],
+        'INFOPLIST_FILE': 'ExtensionContainer/Info.plist',
+        'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
+        'ARCHS': [ 'armv7' ],
+        'SDKROOT': 'iphoneos',
+        'IPHONEOS_DEPLOYMENT_TARGET': '7.0',
+      },
+    },
+    {
+      'target_name': 'ActionExtension',
+      'product_name': 'ActionExtension',
+      'type': 'executable',
+      'mac_bundle': 1,
+      'ios_app_extension': 1,
+      'sources': [
+        'ActionExtension/ActionViewController.h',
+        'ActionExtension/ActionViewController.m',
+      ],
+      'link_settings': {
+        'libraries': [
+          '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
+          '$(SDKROOT)/System/Library/Frameworks/UIKit.framework',
+          '$(SDKROOT)/System/Library/Frameworks/MobileCoreServices.framework',
+        ],
+      },
+      'xcode_settings': {
+        'OTHER_CFLAGS': [
+          '-fobjc-abi-version=2',
+        ],
+        'INFOPLIST_FILE': 'ActionExtension/Info.plist',
+        'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
+        'ARCHS': [ 'armv7' ],
+        'SDKROOT': 'iphoneos',
+        'IPHONEOS_DEPLOYMENT_TARGET': '7.0',
+      },
+    },
+  ],
+}
+
diff --git a/test/ios/gyptest-extension.py b/test/ios/gyptest-extension.py
new file mode 100755
index 0000000..103eb3f
--- /dev/null
+++ b/test/ios/gyptest-extension.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies that ios app extensions are built correctly.
+"""
+
+import TestGyp
+import TestMac
+
+import sys
+if sys.platform == 'darwin' and TestMac.Xcode.Version()>="0600":
+  test = TestGyp.TestGyp(formats=['ninja', 'xcode'])
+
+  test.run_gyp('extension.gyp', chdir='extension')
+
+  test.build('extension.gyp', 'ExtensionContainer', chdir='extension')
+
+  # Test that the extension is .appex
+  test.built_file_must_exist(
+      'ExtensionContainer.app/PlugIns/ActionExtension.appex',
+      chdir='extension')
+
+  test.pass_test()
+
diff --git a/test/lib/TestGyp.py b/test/lib/TestGyp.py
index 3cea15e..ff95418 100644
--- a/test/lib/TestGyp.py
+++ b/test/lib/TestGyp.py
@@ -10,12 +10,14 @@
 from contextlib import contextmanager
 import itertools
 import os
+import random
 import re
 import shutil
 import stat
 import subprocess
 import sys
 import tempfile
+import time
 
 import TestCmd
 import TestCommon
@@ -552,7 +554,7 @@
     print stderr.read()
     self.fail_test()
 
-  def _call_adb(self, command):
+  def _call_adb(self, command, timeout=15, retry=3):
     """ Calls the provided adb command.
 
     If the command fails, the test fails.
@@ -571,23 +573,47 @@
         if is_shell:
           command = [command[0], '%s; echo "\n$?";' % ' '.join(command[1:])]
         adb_command += command
-        if subprocess.call(adb_command, stdout=adb_out, stderr=adb_err) != 0:
-          self._adb_failure(adb_command, None, adb_out, adb_err)
-        else:
+
+        for attempt in xrange(1, retry + 1):
           adb_out.seek(0)
-          output = adb_out.read()
-          if is_shell:
-            output = output.splitlines(True)
+          adb_out.truncate(0)
+          adb_err.seek(0)
+          adb_err.truncate(0)
+          proc = subprocess.Popen(adb_command, stdout=adb_out, stderr=adb_err)
+          deadline = time.time() + timeout
+          timed_out = False
+          while proc.poll() is None and not timed_out:
+            time.sleep(1)
+            timed_out = time.time() > deadline
+          if timed_out:
+            print 'Timeout for command %s (attempt %d of %s)' % (
+                adb_command, attempt, retry)
             try:
-              output[-2] = output[-2].rstrip('\r\n')
-              output, rc = (''.join(output[:-1]), int(output[-1]))
-            except ValueError:
-              self._adb_failure(adb_command, 'unexpected output format',
-                                adb_out, adb_err)
-            if rc != 0:
-              self._adb_failure(adb_command, 'exited with %d' % rc, adb_out,
-                                adb_err)
-          return output
+              proc.kill()
+            except:
+              pass
+          else:
+            break
+
+        if proc.returncode != 0:  # returncode is None in the case of a timeout.
+          self._adb_failure(
+              adb_command, 'retcode=%s' % proc.returncode, adb_out, adb_err)
+          return
+
+        adb_out.seek(0)
+        output = adb_out.read()
+        if is_shell:
+          output = output.splitlines(True)
+          try:
+            output[-2] = output[-2].rstrip('\r\n')
+            output, rc = (''.join(output[:-1]), int(output[-1]))
+          except ValueError:
+            self._adb_failure(adb_command, 'unexpected output format',
+                              adb_out, adb_err)
+          if rc != 0:
+            self._adb_failure(adb_command, 'exited with %d' % rc, adb_out,
+                              adb_err)
+        return output
 
   def run_built_executable(self, name, *args, **kw):
     """
@@ -620,7 +646,9 @@
 
       out = self._call_adb(
           ['shell', 'LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s' % storage,
-           device_executable])
+           device_executable],
+          timeout=60,
+          retry=1)
       out = out.replace('\r\n', '\n')
       self._complete(out, kw.pop('stdout', None), None, None, None, match)
     finally:
diff --git a/test/mac/gyptest-loadable-module-bundle-product-extension.py b/test/mac/gyptest-loadable-module-bundle-product-extension.py
new file mode 100644
index 0000000..90c2083
--- /dev/null
+++ b/test/mac/gyptest-loadable-module-bundle-product-extension.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Tests that loadable_modules don't collide when using the same name with
+different file extensions.
+"""
+
+import TestGyp
+
+import os
+import struct
+import sys
+
+if sys.platform == 'darwin':
+  test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode'])
+
+  CHDIR = 'loadable-module-bundle-product-extension'
+  test.run_gyp('test.gyp', chdir=CHDIR)
+  test.build('test.gyp', test.ALL, chdir=CHDIR)
+
+  test.must_exist(test.built_file_path('Collide.foo', chdir=CHDIR))
+  test.must_exist(test.built_file_path('Collide.bar', chdir=CHDIR))
+
+  test.pass_test()
diff --git a/test/mac/loadable-module-bundle-product-extension/src.cc b/test/mac/loadable-module-bundle-product-extension/src.cc
new file mode 100644
index 0000000..3d878e9
--- /dev/null
+++ b/test/mac/loadable-module-bundle-product-extension/src.cc
@@ -0,0 +1,7 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+int test() {
+  return 1337;
+}
diff --git a/test/mac/loadable-module-bundle-product-extension/test.gyp b/test/mac/loadable-module-bundle-product-extension/test.gyp
new file mode 100644
index 0000000..684a2c0
--- /dev/null
+++ b/test/mac/loadable-module-bundle-product-extension/test.gyp
@@ -0,0 +1,24 @@
+# Copyright (c) 2014 Google Inc. 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': 'test',
+    'type': 'none',
+    'dependencies': ['child_one', 'child_two'],
+  }, {
+    'target_name': 'child_one',
+    'product_name': 'Collide',
+    'product_extension': 'bar',
+    'sources': ['src.cc'],
+    'type': 'loadable_module',
+    'mac_bundle': 1,
+  }, {
+    'target_name': 'child_two',
+    'product_name': 'Collide',
+    'product_extension': 'foo',
+    'sources': ['src.cc'],
+    'type': 'loadable_module',
+    'mac_bundle': 1,
+  }],
+}
diff --git a/test/make_global_settings/full-toolchain/bar.cc b/test/make_global_settings/full-toolchain/bar.cc
new file mode 100644
index 0000000..afb422b
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/bar.cc
@@ -0,0 +1 @@
+#error Not a real source file
diff --git a/test/make_global_settings/full-toolchain/foo.c b/test/make_global_settings/full-toolchain/foo.c
new file mode 100644
index 0000000..afb422b
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/foo.c
@@ -0,0 +1 @@
+#error Not a real source file
diff --git a/test/make_global_settings/full-toolchain/gyptest-make_global_settings.py b/test/make_global_settings/full-toolchain/gyptest-make_global_settings.py
new file mode 100644
index 0000000..0dd148c
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/gyptest-make_global_settings.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies make_global_settings works with the full toolchain.
+"""
+
+import os
+import sys
+import TestGyp
+
+if sys.platform == 'win32':
+  # cross compiling not supported by ninja on windows
+  # and make not supported on windows at all.
+  sys.exit(0)
+
+test = TestGyp.TestGyp(formats=['ninja'])
+# Must set the test format to something with a flavor (the part after the '-')
+# in order to test the desired behavior. Since we want to run a non-host
+# toolchain, we have to set the flavor to something that the ninja generator
+# doesn't know about, so it doesn't default to the host-specific tools (e.g.,
+# 'otool' on mac to generate the .TOC).
+#
+# Note that we can't just pass format=['ninja-some_toolchain'] to the
+# constructor above, because then this test wouldn't be recognized as a ninja
+# format test.
+test.formats = ['ninja-some_flavor']
+
+gyp_file = 'make_global_settings.gyp'
+
+test.run_gyp(gyp_file,
+             # Teach the .gyp file about the location of my_nm.py and
+             # my_readelf.py, and the python executable.
+             '-Dworkdir=%s' % test.workdir,
+             '-Dpython=%s' % sys.executable)
+test.build(gyp_file, arguments=['-v'])
+
+expected = ['MY_CC', 'MY_CXX']
+test.must_contain_all_lines(test.stdout(), expected)
+
+test.must_contain(test.built_file_path('RAN_MY_NM'), 'RAN_MY_NM')
+test.must_contain(test.built_file_path('RAN_MY_READELF'), 'RAN_MY_READELF')
+
+test.pass_test()
diff --git a/test/make_global_settings/full-toolchain/make_global_settings.gyp b/test/make_global_settings/full-toolchain/make_global_settings.gyp
new file mode 100644
index 0000000..2c32663
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/make_global_settings.gyp
@@ -0,0 +1,22 @@
+# Copyright (c) 2013 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style licence that can be
+# found in the LICENSE file.
+
+{
+  'make_global_settings': [
+    ['CC', '/bin/echo MY_CC'],
+    ['CXX', '/bin/echo MY_CXX'],
+    ['NM', '<(python) <(workdir)/my_nm.py'],
+    ['READELF', '<(python) <(workdir)/my_readelf.py'],
+  ],
+  'targets': [
+    {
+      'target_name': 'test',
+      'type': 'shared_library',
+      'sources': [
+        'foo.c',
+        'bar.cc',
+      ],
+    },
+  ],
+}
diff --git a/test/make_global_settings/full-toolchain/my_nm.py b/test/make_global_settings/full-toolchain/my_nm.py
new file mode 100755
index 0000000..f0f1efc
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/my_nm.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import sys
+print sys.argv
+with open('RAN_MY_NM', 'w') as f:
+  f.write('RAN_MY_NM')
diff --git a/test/make_global_settings/full-toolchain/my_readelf.py b/test/make_global_settings/full-toolchain/my_readelf.py
new file mode 100755
index 0000000..40e303c
--- /dev/null
+++ b/test/make_global_settings/full-toolchain/my_readelf.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import sys
+print sys.argv
+with open('RAN_MY_READELF', 'w') as f:
+  f.write('RAN_MY_READELF')
diff --git a/test/msvs/multiple_actions_error_handling/action_fail.py b/test/msvs/multiple_actions_error_handling/action_fail.py
new file mode 100644
index 0000000..286fc4e
--- /dev/null
+++ b/test/msvs/multiple_actions_error_handling/action_fail.py
@@ -0,0 +1,7 @@
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+
+sys.exit(1)
diff --git a/test/msvs/multiple_actions_error_handling/action_succeed.py b/test/msvs/multiple_actions_error_handling/action_succeed.py
new file mode 100644
index 0000000..3554373
--- /dev/null
+++ b/test/msvs/multiple_actions_error_handling/action_succeed.py
@@ -0,0 +1,7 @@
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+
+sys.exit(0)
diff --git a/test/msvs/multiple_actions_error_handling/actions.gyp b/test/msvs/multiple_actions_error_handling/actions.gyp
new file mode 100644
index 0000000..ab99e92
--- /dev/null
+++ b/test/msvs/multiple_actions_error_handling/actions.gyp
@@ -0,0 +1,40 @@
+# Copyright (c) 2014 Google Inc. 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': 'actions-test',
+      'type': 'none',
+      'actions': [
+        {
+          'action_name': 'first action (fails)',
+          'inputs': [
+            'action_fail.py',
+          ],
+          'outputs': [
+            'ALWAYS_OUT_OF_DATE',
+          ],
+          'action': [
+            'python', '<@(_inputs)'
+          ],
+          'msvs_cygwin_shell': 0,
+        },
+        {
+          'action_name': 'second action (succeeds)',
+          'inputs': [
+            'action_succeed.py',
+          ],
+          'outputs': [
+            'ALWAYS_OUT_OF_DATE',
+          ],
+          'action': [
+            'python', '<@(_inputs)'
+          ],
+          'msvs_cygwin_shell': 0,
+        },
+      ],
+    },
+  ],
+}
diff --git a/test/msvs/multiple_actions_error_handling/gyptest.py b/test/msvs/multiple_actions_error_handling/gyptest.py
new file mode 100644
index 0000000..3aa6b8f
--- /dev/null
+++ b/test/msvs/multiple_actions_error_handling/gyptest.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies that failing actions make the build fail reliably, even when there
+are multiple actions in one project.
+"""
+
+import os
+import sys
+import TestGyp
+import TestCmd
+
+test = TestGyp.TestGyp(formats=['msvs'], workdir='workarea_all')
+
+test.run_gyp('actions.gyp')
+test.build('actions.gyp',
+           target='actions-test',
+           status=1,
+           stdout=r'.*"cmd\.exe" exited with code 1\..*',
+           match=TestCmd.match_re_dotall)
+
+test.pass_test()
diff --git a/test/ninja/empty-and-non-empty-duplicate-name/gyptest-empty-and-non-empty-duplicate-name.py b/test/ninja/empty-and-non-empty-duplicate-name/gyptest-empty-and-non-empty-duplicate-name.py
new file mode 100644
index 0000000..1279ead
--- /dev/null
+++ b/test/ninja/empty-and-non-empty-duplicate-name/gyptest-empty-and-non-empty-duplicate-name.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Verifies a phony target isn't output if a target exists with the same name that
+was output.
+"""
+
+import TestGyp
+
+test = TestGyp.TestGyp(formats=['ninja'])
+
+test.run_gyp('test.gyp')
+
+# Check for both \r and \n to cover both windows and linux.
+test.must_not_contain('out/Default/build.ninja', 'build empty_target: phony\r')
+test.must_not_contain('out/Default/build.ninja', 'build empty_target: phony\n')
+
+test.pass_test()
diff --git a/test/ninja/empty-and-non-empty-duplicate-name/subdir/included.gyp b/test/ninja/empty-and-non-empty-duplicate-name/subdir/included.gyp
new file mode 100644
index 0000000..1b9fc42
--- /dev/null
+++ b/test/ninja/empty-and-non-empty-duplicate-name/subdir/included.gyp
@@ -0,0 +1,19 @@
+# Copyright (c) 2014 Google Inc. 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': 'empty_target',
+      'type': 'executable',
+      'sources': [
+        'test.cc',
+      ],
+    },
+    {
+      'target_name': 'included_empty_target',
+      'type': 'none',
+    },
+  ],
+}
diff --git a/test/ninja/empty-and-non-empty-duplicate-name/test.gyp b/test/ninja/empty-and-non-empty-duplicate-name/test.gyp
new file mode 100644
index 0000000..9aa6287
--- /dev/null
+++ b/test/ninja/empty-and-non-empty-duplicate-name/test.gyp
@@ -0,0 +1,19 @@
+# Copyright (c) 2014 Google Inc. 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': 'All',
+      'type': 'none',
+      'dependencies': [
+        'subdir/included.gyp:included_empty_target'
+      ]
+    },
+    {
+      'target_name': 'empty_target',
+      'type': 'none',
+    },
+  ],
+}
diff --git a/test/ninja/use-console/foo.bar b/test/ninja/use-console/foo.bar
new file mode 100644
index 0000000..07c476a
--- /dev/null
+++ b/test/ninja/use-console/foo.bar
@@ -0,0 +1,5 @@
+# Copyright (c) 2014 Google Inc. 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 a dummy file for rule/action input.
diff --git a/test/ninja/use-console/gyptest-use-console.py b/test/ninja/use-console/gyptest-use-console.py
new file mode 100644
index 0000000..f76fcd9
--- /dev/null
+++ b/test/ninja/use-console/gyptest-use-console.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Make sure 'ninja_use_console' is supported in actions and rules.
+"""
+
+import TestGyp
+
+test = TestGyp.TestGyp(formats=['ninja'])
+
+test.run_gyp('use-console.gyp')
+
+no_pool = open(test.built_file_path('obj/no_pool.ninja')).read()
+if 'pool =' in no_pool:
+  test.fail_test()
+
+action_pool = open(test.built_file_path('obj/action_pool.ninja')).read()
+if 'pool = console' not in action_pool:
+  test.fail_test()
+
+rule_pool = open(test.built_file_path('obj/rule_pool.ninja')).read()
+if 'pool = console' not in rule_pool:
+  test.fail_test()
+
+test.pass_test()
diff --git a/test/ninja/use-console/use-console.gyp b/test/ninja/use-console/use-console.gyp
new file mode 100644
index 0000000..84e6318
--- /dev/null
+++ b/test/ninja/use-console/use-console.gyp
@@ -0,0 +1,60 @@
+# Copyright (c) 2014 Google Inc. 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': 'no_pool',
+      'type': 'none',
+      'actions': [
+        {
+          'action_name': 'some_action',
+          'action': ['echo', 'hello'],
+          'inputs': ['foo.bar'],
+          'outputs': ['dummy'],
+        },
+      ],
+      'rules': [
+        {
+          'rule_name': 'some_rule',
+          'extension': 'bar',
+          'action': ['echo', 'hello'],
+          'outputs': ['dummy'],
+        },
+      ],
+      'sources': [
+        'foo.bar',
+      ],
+    },
+    {
+      'target_name': 'action_pool',
+      'type': 'none',
+      'actions': [
+        {
+          'action_name': 'some_action',
+          'action': ['echo', 'hello'],
+          'inputs': ['foo.bar'],
+          'outputs': ['dummy'],
+          'ninja_use_console': 1,
+        },
+      ],
+    },
+    {
+      'target_name': 'rule_pool',
+      'type': 'none',
+      'rules': [
+        {
+          'rule_name': 'some_rule',
+          'extension': 'bar',
+          'action': ['echo', 'hello'],
+          'outputs': ['dummy'],
+          'ninja_use_console': 1,
+        },
+      ],
+      'sources': [
+        'foo.bar',
+      ],
+    },
+  ],
+}
diff --git a/test/same-source-file-name/gyptest-fail-shared.py b/test/same-source-file-name/gyptest-fail-shared.py
deleted file mode 100755
index 5b57826..0000000
--- a/test/same-source-file-name/gyptest-fail-shared.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2012 Google Inc. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Checks that gyp fails on shared_library targets which have several files with
-the same basename.
-"""
-
-import TestGyp
-
-test = TestGyp.TestGyp()
-
-test.run_gyp('double-shared.gyp', chdir='src', status=1, stderr=None)
-
-test.pass_test()
diff --git a/test/same-source-file-name/gyptest-fail-static.py b/test/same-source-file-name/gyptest-fail-static.py
deleted file mode 100755
index e84d37c..0000000
--- a/test/same-source-file-name/gyptest-fail-static.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2012 Google Inc. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Checks that gyp fails on static_library targets which have several files with
-the same basename.
-"""
-
-import TestGyp
-
-test = TestGyp.TestGyp()
-
-test.run_gyp('double-static.gyp', chdir='src', status=1, stderr=None)
-
-test.pass_test()
diff --git a/test/same-source-file-name/gyptest-shared.py b/test/same-source-file-name/gyptest-shared.py
new file mode 100755
index 0000000..a57eb61
--- /dev/null
+++ b/test/same-source-file-name/gyptest-shared.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Checks that gyp fails on shared_library targets which have several files with
+the same basename.
+"""
+
+import os
+
+import TestGyp
+
+test = TestGyp.TestGyp()
+
+# Fails by default for the compatibility with Visual C++ 2008 generator.
+# TODO: Update expected behavior when these legacy generators are deprecated.
+test.run_gyp('double-shared.gyp', chdir='src', status=1, stderr=None)
+
+if ((test.format == 'msvs') and
+       (int(os.environ.get('GYP_MSVS_VERSION', 2010)) < 2010)):
+  test.run_gyp('double-shared.gyp', '--no-duplicate-basename-check',
+               chdir='src', status=0, stderr=None)
+else:
+  test.run_gyp('double-shared.gyp', '--no-duplicate-basename-check',
+               chdir='src')
+  test.build('double-shared.gyp', test.ALL, chdir='src')
+
+test.pass_test()
diff --git a/test/same-source-file-name/gyptest-static.py b/test/same-source-file-name/gyptest-static.py
new file mode 100755
index 0000000..7fa2772
--- /dev/null
+++ b/test/same-source-file-name/gyptest-static.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Checks that gyp fails on static_library targets which have several files with
+the same basename.
+"""
+
+import os
+import sys
+
+import TestGyp
+
+test = TestGyp.TestGyp()
+
+# Fails by default for the compatibility with legacy generators such as
+# VCProj generator for Visual C++ 2008 and Makefile generator on Mac.
+# TODO: Update expected behavior when these legacy generators are deprecated.
+test.run_gyp('double-static.gyp', chdir='src', status=1, stderr=None)
+
+if ((test.format == 'make' and sys.platform == 'darwin') or
+    (test.format == 'msvs' and
+        int(os.environ.get('GYP_MSVS_VERSION', 2010)) < 2010)):
+  test.run_gyp('double-static.gyp', '--no-duplicate-basename-check',
+               chdir='src', status=1, stderr=None)
+else:
+  test.run_gyp('double-static.gyp', '--no-duplicate-basename-check',
+               chdir='src')
+  test.build('double-static.gyp', test.ALL, chdir='src')
+
+test.pass_test()
diff --git a/test/same-source-file-name/src/double-shared.gyp b/test/same-source-file-name/src/double-shared.gyp
index 40d995f..438b50f 100644
--- a/test/same-source-file-name/src/double-shared.gyp
+++ b/test/same-source-file-name/src/double-shared.gyp
@@ -6,6 +6,7 @@
   'targets': [
     {
       'target_name': 'lib',
+      'product_name': 'test_shared_lib',
       'type': 'shared_library',
       'sources': [
         'prog2.c',
@@ -16,6 +17,11 @@
       'defines': [
         'PROG="prog2"',
       ],
+      'conditions': [
+        ['OS=="linux"', {
+          'cflags': ['-fPIC'],
+        }],
+      ],
     },
   ],
 }
diff --git a/test/same-source-file-name/src/double-static.gyp b/test/same-source-file-name/src/double-static.gyp
index 3da1242..e49c0e1 100644
--- a/test/same-source-file-name/src/double-static.gyp
+++ b/test/same-source-file-name/src/double-static.gyp
@@ -6,6 +6,7 @@
   'targets': [
     {
       'target_name': 'lib',
+      'product_name': 'test_static_lib',
       'type': 'static_library',
       'sources': [
         'prog1.c',
diff --git a/test/win/gyptest-link-pdb-no-output.py b/test/win/gyptest-link-pdb-no-output.py
new file mode 100644
index 0000000..6da0aea
--- /dev/null
+++ b/test/win/gyptest-link-pdb-no-output.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Ensure that when debug information is not output, a pdb is not expected.
+"""
+
+import TestGyp
+
+import os
+import sys
+
+if sys.platform == 'win32':
+  test = TestGyp.TestGyp()
+  CHDIR = 'linker-flags'
+  test.run_gyp('pdb-output.gyp', chdir=CHDIR)
+  test.build('pdb-output.gyp', 'test_pdb_output_disabled', chdir=CHDIR)
+  # Make sure that the build doesn't expect a PDB to be generated when there
+  # will be none.
+  test.up_to_date('pdb-output.gyp', 'test_pdb_output_disabled', chdir=CHDIR)
+
+  test.pass_test()
diff --git a/test/win/gyptest-link-pdb-output.py b/test/win/gyptest-link-pdb-output.py
index 8080410..27245f7 100644
--- a/test/win/gyptest-link-pdb-output.py
+++ b/test/win/gyptest-link-pdb-output.py
@@ -31,4 +31,3 @@
     test.fail_test()
 
   test.pass_test()
-
diff --git a/test/win/gyptest-system-include.py b/test/win/gyptest-system-include.py
new file mode 100644
index 0000000..9a47d98
--- /dev/null
+++ b/test/win/gyptest-system-include.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Checks that msvs_system_include_dirs works.
+"""
+
+import TestGyp
+
+import sys
+
+if sys.platform == 'win32':
+  test = TestGyp.TestGyp(formats=['msvs', 'ninja'])
+
+  CHDIR = 'system-include'
+  test.run_gyp('test.gyp', chdir=CHDIR)
+  test.build('test.gyp', test.ALL, chdir=CHDIR)
+  test.pass_test()
diff --git a/test/win/idl-rules/Window.idl b/test/win/idl-rules/Window.idl
new file mode 100644
index 0000000..d8ea01b
--- /dev/null
+++ b/test/win/idl-rules/Window.idl
@@ -0,0 +1,9 @@
+// Copyright (c) 2014 Google Inc. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+    WillBeGarbageCollected,
+] interface Window {
+    void alert();
+};
diff --git a/test/win/idl-rules/basic-idl.gyp b/test/win/idl-rules/basic-idl.gyp
index 9c08327..b74622a 100644
--- a/test/win/idl-rules/basic-idl.gyp
+++ b/test/win/idl-rules/basic-idl.gyp
@@ -1,42 +1,67 @@
-# 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.

-

-{

-  'variables': {

-    'midl_out_dir': '<(SHARED_INTERMEDIATE_DIR)',

-  },

-  'target_defaults': {

-    'configurations': {

-      'Debug': {

-        'msvs_configuration_platform': 'Win32',

-      },

-      'Debug_x64': {

-        'inherit_from': ['Debug'],

-        'msvs_configuration_platform': 'x64',

-      },

-    },

-  },

-  'targets': [

-    {

-      'target_name': 'idl_test',

-      'type': 'executable',

-      'sources': [

-        'history_indexer.idl',

-        '<(midl_out_dir)/history_indexer.h',

-        '<(midl_out_dir)/history_indexer_i.c',

-        'history_indexer_user.cc',

-      ],

-      'libraries': ['ole32.lib'],

-      'include_dirs': [

-        '<(midl_out_dir)',

-      ],

-      'msvs_settings': {

-        'VCMIDLTool': {

-          'OutputDirectory': '<(midl_out_dir)',

-          'HeaderFileName': '<(RULE_INPUT_ROOT).h',

-         },

-      },

-    },

-  ],

-}

+# 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.
+
+{
+  'variables': {
+    'midl_out_dir': '<(SHARED_INTERMEDIATE_DIR)',
+  },
+  'target_defaults': {
+    'configurations': {
+      'Debug': {
+        'msvs_configuration_platform': 'Win32',
+      },
+      'Debug_x64': {
+        'inherit_from': ['Debug'],
+        'msvs_configuration_platform': 'x64',
+      },
+    },
+  },
+  'targets': [
+    {
+      'target_name': 'idl_test',
+      'type': 'executable',
+      'sources': [
+        'history_indexer.idl',
+        '<(midl_out_dir)/history_indexer.h',
+        '<(midl_out_dir)/history_indexer_i.c',
+        'history_indexer_user.cc',
+      ],
+      'libraries': ['ole32.lib'],
+      'include_dirs': [
+        '<(midl_out_dir)',
+      ],
+      'msvs_settings': {
+        'VCMIDLTool': {
+          'OutputDirectory': '<(midl_out_dir)',
+          'HeaderFileName': '<(RULE_INPUT_ROOT).h',
+         },
+      },
+    },
+    {
+      'target_name': 'idl_explicit_action',
+      'type': 'none',
+      'sources': [
+        'Window.idl',
+      ],
+      'actions': [{
+        'action_name': 'blink_idl',
+        'explicit_idl_action': 1,
+        'msvs_cygwin_shell': 0,
+        'inputs': [
+          'Window.idl',
+          'idl_compiler.py',
+        ],
+        'outputs': [
+          'Window.cpp',
+          'Window.h',
+        ],
+        'action': [
+          'python',
+          'idl_compiler.py',
+          'Window.idl',
+        ],
+      }],
+    },
+  ],
+}
diff --git a/test/win/idl-rules/idl_compiler.py b/test/win/idl-rules/idl_compiler.py
new file mode 100644
index 0000000..a12b274
--- /dev/null
+++ b/test/win/idl-rules/idl_compiler.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2014 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# mock, just outputs empty .h/.cpp files
+
+import os
+import sys
+
+if len(sys.argv) == 2:
+  basename, ext = os.path.splitext(sys.argv[1])
+  with open('%s.h' % basename, 'w') as f:
+    f.write('// %s.h\n' % basename)
+  with open('%s.cpp' % basename, 'w') as f:
+    f.write('// %s.cpp\n' % basename)
diff --git a/test/win/linker-flags/pdb-output.gyp b/test/win/linker-flags/pdb-output.gyp
index 21d3cd7..1a03c67 100644
--- a/test/win/linker-flags/pdb-output.gyp
+++ b/test/win/linker-flags/pdb-output.gyp
@@ -32,5 +32,18 @@
         },
       },
     },
+    {
+      'target_name': 'test_pdb_output_disabled',
+      'type': 'executable',
+      'sources': ['hello.cc'],
+      'msvs_settings': {
+        'VCCLCompilerTool': {
+          'DebugInformationFormat': '0'
+        },
+        'VCLinkerTool': {
+          'GenerateDebugInformation': 'false',
+        },
+      },
+    },
   ]
 }
diff --git a/test/win/system-include/bar/header.h b/test/win/system-include/bar/header.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/win/system-include/bar/header.h
diff --git a/test/win/system-include/common/commonheader.h b/test/win/system-include/common/commonheader.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/win/system-include/common/commonheader.h
diff --git a/test/win/system-include/foo/header.h b/test/win/system-include/foo/header.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/win/system-include/foo/header.h
diff --git a/test/win/system-include/main.cc b/test/win/system-include/main.cc
new file mode 100644
index 0000000..b04ea8a
--- /dev/null
+++ b/test/win/system-include/main.cc
@@ -0,0 +1,4 @@
+#include <commonheader.h>
+#include <header.h>
+
+int main() {}
diff --git a/test/win/system-include/test.gyp b/test/win/system-include/test.gyp
new file mode 100644
index 0000000..07f2636
--- /dev/null
+++ b/test/win/system-include/test.gyp
@@ -0,0 +1,26 @@
+{
+  'target_defaults': {
+    'msvs_settings': {
+      'VCCLCompilerTool': {
+        'WarningLevel': '4',
+        'WarnAsError': 'true',
+      },
+    },
+    'msvs_system_include_dirs': [
+      '$(ProjectName)',  # Different for each target
+      'common',  # Same for all targets
+    ],
+  },
+  'targets': [
+    {
+      'target_name': 'foo',
+      'type': 'executable',
+      'sources': [ 'main.cc', ],
+    },
+    {
+      'target_name': 'bar',
+      'type': 'executable',
+      'sources': [ 'main.cc', ],
+    },
+  ],
+}
diff --git a/tools/emacs/gyp.el b/tools/emacs/gyp.el
index 3db9f64..60619b5 100644
--- a/tools/emacs/gyp.el
+++ b/tools/emacs/gyp.el
@@ -15,14 +15,15 @@
                  "recent emacsen), not from the older and less maintained "
                  "python-mode.el")))
 
-(defadvice python-calculate-indentation (after ami-outdent-closing-parens
-                                               activate)
+(defadvice python-indent-calculate-levels (after gyp-outdent-closing-parens
+                                                 activate)
   "De-indent closing parens, braces, and brackets in gyp-mode."
-  (if (and (eq major-mode 'gyp-mode)
-           (string-match "^ *[])}][],)}]* *$"
-                         (buffer-substring-no-properties
-                          (line-beginning-position) (line-end-position))))
-      (setq ad-return-value (- ad-return-value 2))))
+  (when (and (eq major-mode 'gyp-mode)
+             (string-match "^ *[])}][],)}]* *$"
+                           (buffer-substring-no-properties
+                            (line-beginning-position) (line-end-position))))
+    (setf (first python-indent-levels)
+          (- (first python-indent-levels) python-indent-offset))))
 
 (define-derived-mode gyp-mode python-mode "Gyp"
   "Major mode for editing .gyp files. See http://code.google.com/p/gyp/"
@@ -36,8 +37,8 @@
 (defun gyp-set-indentation ()
   "Hook function to configure python indentation to suit gyp mode."
   (setq python-continuation-offset 2
-        python-indent 2
-        python-guess-indent nil))
+        python-indent-offset 2
+        python-indent-guess-indent-offset nil))
 
 (add-hook 'gyp-mode-hook 'gyp-set-indentation)
 
@@ -218,8 +219,8 @@
     ;; Top-level keywords
     (list (concat "['\"]\\("
               (regexp-opt (list "action" "action_name" "actions" "cflags"
-                                "conditions" "configurations" "copies" "defines"
-                                "dependencies" "destination"
+                                "cflags_cc" "conditions" "configurations"
+                                "copies" "defines" "dependencies" "destination"
                                 "direct_dependent_settings"
                                 "export_dependent_settings" "extension" "files"
                                 "include_dirs" "includes" "inputs" "libraries"