CmltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsKaW1wb3J0IGpkYm0uUmVjb3JkTWFuYWdlcjsKaW1wb3J0IGpkYm0uUmVjb3JkTWFuYWdlckZhY3Rvcnk7CgppbXBvcnQgamRibS5oZWxwZXIuVHVwbGU7CmltcG9ydCBqZGJtLmhlbHBlci5UdXBsZUJyb3dzZXI7CmltcG9ydCBqZGJtLmhlbHBlci5TdHJpbmdDb21wYXJhdG9yOwoKaW1wb3J0IGpkYm0uYnRyZWUuQlRyZWU7CgovKioKICogRmFtb3VzIFBlb3BsZSBleGFtcGxlLgogKiA8cD4KICogRGVtb25zdHJhdGVzIHRoZSB1c2Ugb2YgQitUcmVlIGRhdGEgc3RydWN0dXJlIHRvIG1hbmFnZSBhIGxpc3Qgb2YKICogcGVvcGxlIGFuZCB0aGVpciBvY2N1cGF0aW9uLiAgVGhlIGV4YW1wbGUgY292ZXJzIGluc2VydGlvbiwKICogb3JkZXJlZCB0cmF2ZXJzYWwsIHJldmVyc2UgdHJhdmVyc2FsIGFuZCByYW5nZSBsb29rdXAgb2YgcmVjb3Jkcy4KICoKICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86Ym9pc3ZlcnRAaW50YWxpby5jb20iPkFsZXggQm9pc3ZlcnQ8L2E+CiAqIEB2ZXJzaW9uICRJZDogRmFtb3VzUGVvcGxlLmphdmEsdiAxLjYgMjAwMy8xMC8yMSAxNTozMjowMiBib2lzdmVydCBFeHAgJAogKi8KcHVibGljIGNsYXNzIEZhbW91c1Blb3BsZSB7CgogICAgc3RhdGljIFN0cmluZyBEQVRBQkFTRSA9ICJwZW9wbGUiOwogICAgc3RhdGljIFN0cmluZyBCVFJFRV9OQU1FID0gIkZhbW91c1Blb3BsZSI7CgogICAgc3RhdGljIFN0cmluZ1tdIHBlb3BsZSA9CiAgICAgICAgeyAiR3JlZW5zcGFuLCBBbGFuIiwKICAgICAgICAgICJXaWxsaWFtcy1CeXJkLCBKdWxpZSIsCiAgICAgICAgICAiUGljYXNzbywgUGFibG8iLAogICAgICAgICAgIlN0YWxsbWFuLCBSaWNoYXJkIiwKICAgICAgICAgICJGb3J0LCBQYXVsIiwKICAgICAgICAgICJT+G5kZXJnYWFyZCwgT2xlIiwKICAgICAgICAgICJTY2h3YXJ6ZW5lZ2dlciwgQXJub2xkIiwKICAgICAgICAgICJEdWxraW55cywgU3VzYW5uYSIgfTsKCiAgICBzdGF0aWMgU3RyaW5nW10gb2NjdXBhdGlvbnMgPQogICAgICAgIHsgIkZlZGVyYWwgUmVzZXJ2ZSBCb2FyZCBDaGFpcm1hbiIsCiAgICAgICAgICAiRW5naW5lZXIiLAogICAgICAgICAgIlBhaW50ZXIiLAogICAgICAgICAgIlByb2dyYW1tZXIiLAogICAgICAgICAgIlBvZXQiLAogICAgICAgICAgIlR5cG9ncmFwaGVyIiwKICAgICAgICAgICJBY3RvciIsCiAgICAgICAgICAiRGVzaWduZXIiIH07CgogICAgc3RhdGljIFN0cmluZyBQUkVGSVggPSAiUyI7CgogICAgLyoqCiAgICAgKiBFeGFtcGxlIG1haW4gZW50cnlwb2ludC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oIFN0cmluZ1tdIGFyZ3MgKSB7CiAgICAgICAgUmVjb3JkTWFuYWdlciByZWNtYW47CiAgICAgICAgbG9uZyAgICAgICAgICByZWNpZDsKICAgICAgICBUdXBsZSAgICAgICAgIHR1cGxlID0gbmV3IFR1cGxlKCk7CiAgICAgICAgVHVwbGVCcm93c2VyICBicm93c2VyOwogICAgICAgIEJUcmVlICAgICAgICAgdHJlZTsKICAgICAgICBQcm9wZXJ0aWVzICAgIHByb3BzOwoKICAgICAgICBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIC8vIG9wZW4gZGF0YWJhc2UgYW5kIHNldHVwIGFuIG9iamVjdCBjYWNoZQogICAgICAgICAgICByZWNtYW4gPSBSZWNvcmRNYW5hZ2VyRmFjdG9yeS5jcmVhdGVSZWNvcmRNYW5hZ2VyKCBEQVRBQkFTRSwgcHJvcHMgKTsKCiAgICAgICAgICAgIC8vIHRyeSB0byByZWxvYWQgYW4gZXhpc3RpbmcgQitUcmVlCiAgICAgICAgICAgIHJlY2lkID0gcmVjbWFuLmdldE5hbWVkT2JqZWN0KCBCVFJFRV9OQU1FICk7CiAgICAgICAgICAgIGlmICggcmVjaWQgIT0gMCApIHsKICAgICAgICAgICAgICAgIHRyZWUgPSBCVHJlZS5sb2FkKCByZWNtYW4sIHJlY2lkICk7CiAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJSZWxvYWRlZCBleGlzdGluZyBCVHJlZSB3aXRoICIgKyB0cmVlLnNpemUoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgZmFtb3VzIHBlb3BsZS4iICk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBjcmVhdGUgYSBuZXcgQitUcmVlIGRhdGEgc3RydWN0dXJlIGFuZCB1c2UgYSBTdHJpbmdDb21wYXJhdG9yCiAgICAgICAgICAgICAgICAvLyB0byBvcmRlciB0aGUgcmVjb3JkcyBiYXNlZCBvbiBwZW9wbGUncyBuYW1lLgogICAgICAgICAgICAgICAgdHJlZSA9IEJUcmVlLmNyZWF0ZUluc3RhbmNlKCByZWNtYW4sIG5ldyBTdHJpbmdDb21wYXJhdG9yKCkgKTsKICAgICAgICAgICAgICAgIHJlY21hbi5zZXROYW1lZE9iamVjdCggQlRSRUVfTkFNRSwgdHJlZS5nZXRSZWNpZCgpICk7CiAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJDcmVhdGVkIGEgbmV3IGVtcHR5IEJUcmVlIiApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBpbnNlcnQgcGVvcGxlIHdpdGggdGhlaXIgcmVzcGVjdGl2ZSBvY2N1cGF0aW9uCiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwogICAgICAgICAgICBmb3IgKCBpbnQgaT0wOyBpPHBlb3BsZS5sZW5ndGg7IGkrKyApIHsKICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiggIkluc2VydDogIiArIHBlb3BsZVtpXSApOwogICAgICAgICAgICAgICAgdHJlZS5pbnNlcnQoIHBlb3BsZVsgaSBdLCBvY2N1cGF0aW9uc1sgaSBdLCBmYWxzZSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBtYWtlIHRoZSBkYXRhIHBlcnNpc3RlbnQgaW4gdGhlIGRhdGFiYXNlCiAgICAgICAgICAgIHJlY21hbi5jb21taXQoKTsKCiAgICAgICAgICAgIC8vIHNob3cgbGlzdCBvZiBwZW9wbGUgd2l0aCB0aGVpciBvY2N1cGF0aW9uCiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJQZXJzb24gICAgICAgICAgICAgICAgICAgT2NjdXBhdGlvbiAgICAgICAiICk7CiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbiggIi0tLS0tLS0tLS0tLS0tLS0tLSAgICAgICAtLS0tLS0tLS0tLS0tLS0tLS0iICk7CgogICAgICAgICAgICAvLyB0cmF2ZXJzZSBwZW9wbGUgaW4gb3JkZXIKICAgICAgICAgICAgYnJvd3NlciA9IHRyZWUuYnJvd3NlKCk7CiAgICAgICAgICAgIHdoaWxlICggYnJvd3Nlci5nZXROZXh0KCB0dXBsZSApICkgewogICAgICAgICAgICAgICAgcHJpbnQoIHR1cGxlICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHRyYXZlcnNlIHBlb3BsZSBpbiByZXZlcnNlIG9yZGVyCiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJSZXZlcnNlIG9yZGVyOiIgKTsKICAgICAgICAgICAgYnJvd3NlciA9IHRyZWUuYnJvd3NlKCBudWxsICk7IC8vIHBvc2l0aW9uIGJyb3dzZXIgYXQgZW5kIG9mIHRoZSBsaXN0CgogICAgICAgICAgICB3aGlsZSAoIGJyb3dzZXIuZ2V0UHJldmlvdXMoIHR1cGxlICkgKSB7CiAgICAgICAgICAgICAgICBwcmludCggdHVwbGUgKTsKICAgICAgICAgICAgfQoKCgogICAgICAgICAgICAvLyBkaXNwbGF5IHBlb3BsZSB3aG9zZSBuYW1lIHN0YXJ0IHdpdGggUFJFRklYIHJhbmdlCiAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJBbGwgcGVvcGxlIHdob3NlIG5hbWUgc3RhcnQgd2l0aCAnIiArIFBSRUZJWCArICInOiIgKTsKCiAgICAgICAgICAgIGJyb3dzZXIgPSB0cmVlLmJyb3dzZSggUFJFRklYICk7CiAgICAgICAgICAgIHdoaWxlICggYnJvd3Nlci5nZXROZXh0KCB0dXBsZSApICkgewogICAgICAgICAgICAgICAgU3RyaW5nIGtleSA9IChTdHJpbmcpIHR1cGxlLmdldEtleSgpOwogICAgICAgICAgICAgICAgaWYgKCBrZXkuc3RhcnRzV2l0aCggUFJFRklYICkgKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQoIHR1cGxlICk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgIH0gY2F0Y2ggKCBFeGNlcHRpb24gZXhjZXB0ICkgewogICAgICAgICAgICBleGNlcHQucHJpbnRTdGFja1RyYWNlKCk7CiAgICAgICAgfQogICAgfQoKCiAgICAvKioKICAgICAqIFByaW50IGEgVHVwbGUgY29udGFpbmluZyBhICggUGVyc29uLCBPY2N1cGF0aW9uICkgcGFpci4KICAgICAqLwogICAgc3RhdGljIHZvaWQgcHJpbnQoIFR1cGxlIHR1cGxlICkgewogICAgICAgIFN0cmluZyBwZXJzb24gPSAoU3RyaW5nKSB0dXBsZS5nZXRLZXkoKTsKICAgICAgICBTdHJpbmcgb2NjdXBhdGlvbiA9IChTdHJpbmcpIHR1cGxlLmdldFZhbHVlKCk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCBwYWQoIHBlcnNvbiwgMjUpICsgb2NjdXBhdGlvbiApOwogICAgfQoKCiAgICAvKioKICAgICAqIFBhZCBhIHN0cmluZyB3aXRoIHNwYWNlcyBvbiB0aGUgcmlnaHQuCiAgICAgKgogICAgICogQHBhcmFtIHN0ciBTdHJpbmcgdG8gYWRkIHNwYWNlcwogICAgICogQHBhcmFtIHdpZHRoIFdpZHRoIG9mIHN0cmluZyBhZnRlciBwYWRkaW5nCiAgICAgKi8KICAgIHN0YXRpYyBTdHJpbmcgcGFkKCBTdHJpbmcgc3RyLCBpbnQgd2lkdGggKSB7CiAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoIHN0ciApOwogICAgICAgIGludCBzcGFjZSA9IHdpZHRoLWJ1Zi5sZW5ndGgoKTsKICAgICAgICB3aGlsZSAoIHNwYWNlLS0gPiAwICkgewogICAgICAgICAgICBidWYuYXBwZW5kKCAnICcgKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOwogICAgfQoKfQo=