cGFja2FnZSBvcmcuZWNsaXBzZS54dGVuZC5saWIuYW5ub3RhdGlvbnMKCmltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5hbm5vdGF0aW9ucy5CZXRhCmltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5hbm5vdGF0aW9ucy5Hd3RDb21wYXRpYmxlCmltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZQppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0CmltcG9ydCBqYXZhLnV0aWwuTGlzdAppbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4KaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5BY3RpdmUKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5UcmFuc2Zvcm1hdGlvbkNvbnRleHQKaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5UcmFuc2Zvcm1hdGlvblBhcnRpY2lwYW50CmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uQ2xhc3NEZWNsYXJhdGlvbgppbXBvcnQgb3JnLmVjbGlwc2UueHRlbmQubGliLm1hY3JvLmRlY2xhcmF0aW9uLk11dGFibGVDbGFzc0RlY2xhcmF0aW9uCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uTXV0YWJsZUNvbnN0cnVjdG9yRGVjbGFyYXRpb24KaW1wb3J0IG9yZy5lY2xpcHNlLnh0ZW5kLmxpYi5tYWNyby5kZWNsYXJhdGlvbi5NdXRhYmxlVHlwZURlY2xhcmF0aW9uCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uTXV0YWJsZVR5cGVQYXJhbWV0ZXJEZWNsYXJhdG9yCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uVHlwZURlY2xhcmF0aW9uCmltcG9ydCBvcmcuZWNsaXBzZS54dGVuZC5saWIubWFjcm8uZGVjbGFyYXRpb24uVHlwZVJlZmVyZW5jZQppbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRG9jdW1lbnRlZAoKLyoqCiAqIDxwPkNyZWF0ZXMgYSBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEgcGFyYW1ldGVyIGZvciBlYWNoIGZpbmFsIGZpZWxkIG9mIGEgY2xhc3MuPC9wPgogKiAKICogQW5ub3RhdGVkIG9uIGEgY2xhc3MgCiAqIDxwPgogKiBDcmVhdGVzIGEgY29uc3RydWN0b3IgdGhhdCB0YWtlcyBhbGwKICogbm9uLXN0YXRpYywgZmluYWwgZmllbGRzIG9mIHRoZSBjbGFzcyBhcyBhbiBhcmd1bWVudCBhbmQgYXNzaWducyB0aGVtIHRvCiAqIHRoZWlyIGNvcnJlc3BvbmRpbmcgZmllbGRzLiBUaGUgb3JkZXIgb2YgYXJndW1lbnRzIGlzIHRoZSBzYW1lIGFzIHRoZSBvcmRlcgogKiBvZiB0aGUgZmllbGRzLgogKiA8L3A+CiAqIEFubm90YXRlZCBvbiBhIGNvbnN0cnVjdG9yCiAqIDxwPgogKiBUdXJucyB0aGF0IGNvbnN0cnVjdG9yIGludG8gYSBmaW5hbAogKiBmaWVsZHMgY29uc3RydWN0b3IgYXMgZGVzY3JpYmVkIGFib3ZlLiBUaGlzIGlzIHVzZWZ1bCBmb3IgYWRkaW5nIGFubm90YXRpb25zCiAqIHRvIHRoZSBjb25zdHJ1Y3RvciwgZS5nLiBmb3IgZGVwZW5kZW5jeSBpbmplY3Rpb24gZnJhbWV3b3Jrcy4KICogPC9wPgogKiAKICogQHNpbmNlIDIuNwogKi8KQFRhcmdldChFbGVtZW50VHlwZS5UWVBFLCBFbGVtZW50VHlwZS5DT05TVFJVQ1RPUikKQEd3dENvbXBhdGlibGUKQEJldGEKQEFjdGl2ZShGaW5hbEZpZWxkc0NvbnN0cnVjdG9yUHJvY2Vzc29yKQpARG9jdW1lbnRlZAphbm5vdGF0aW9uIEZpbmFsRmllbGRzQ29uc3RydWN0b3Igewp9CgovKioKICogQHNpbmNlIDIuNwogKiBAbm9leHRlbmQKICogQG5vcmVmZXJlbmNlCiAqLwpAQmV0YQpjbGFzcyBGaW5hbEZpZWxkc0NvbnN0cnVjdG9yUHJvY2Vzc29yIGltcGxlbWVudHMgVHJhbnNmb3JtYXRpb25QYXJ0aWNpcGFudDxNdXRhYmxlVHlwZVBhcmFtZXRlckRlY2xhcmF0b3I+IHsKCglvdmVycmlkZSBkb1RyYW5zZm9ybShMaXN0PD8gZXh0ZW5kcyBNdXRhYmxlVHlwZVBhcmFtZXRlckRlY2xhcmF0b3I+IGVsZW1lbnRzLAoJCWV4dGVuc2lvbiBUcmFuc2Zvcm1hdGlvbkNvbnRleHQgY29udGV4dCkgewoJCWVsZW1lbnRzLmZvckVhY2hbdHJhbnNmb3JtKGNvbnRleHQpXQoJfQoKCWRlZiBkaXNwYXRjaCB2b2lkIHRyYW5zZm9ybShNdXRhYmxlQ2xhc3NEZWNsYXJhdGlvbiBpdCwgZXh0ZW5zaW9uIFRyYW5zZm9ybWF0aW9uQ29udGV4dCBjb250ZXh0KSB7CgkJaWYgKGZpbmRBbm5vdGF0aW9uKERhdGEuZmluZFR5cGVHbG9iYWxseSkgIT09IG51bGwpIHsKCQkJcmV0dXJuCgkJfQoJCWlmIChmaW5kQW5ub3RhdGlvbihBY2Nlc3NvcnMuZmluZFR5cGVHbG9iYWxseSkgIT09IG51bGwpIHsKCQkJcmV0dXJuCgkJfQoJCXZhbCBleHRlbnNpb24gdXRpbCA9IG5ldyBGaW5hbEZpZWxkc0NvbnN0cnVjdG9yUHJvY2Vzc29yLlV0aWwoY29udGV4dCkKCQlhZGRGaW5hbEZpZWxkc0NvbnN0cnVjdG9yCgl9CgoJZGVmIGRpc3BhdGNoIHZvaWQgdHJhbnNmb3JtKE11dGFibGVDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIGl0LCBleHRlbnNpb24gVHJhbnNmb3JtYXRpb25Db250ZXh0IGNvbnRleHQpIHsKCQl2YWwgZXh0ZW5zaW9uIHV0aWwgPSBuZXcgRmluYWxGaWVsZHNDb25zdHJ1Y3RvclByb2Nlc3Nvci5VdGlsKGNvbnRleHQpCgkJbWFrZUZpbmFsRmllbGRzQ29uc3RydWN0b3IKCX0KCgkvKioKCSAqIEBzaW5jZSAyLjcKCSAqIEBub2V4dGVuZAoJICogQG5vcmVmZXJlbmNlCgkgKi8KCUBCZXRhCglzdGF0aWMgY2xhc3MgVXRpbCB7CgkJZXh0ZW5zaW9uIFRyYW5zZm9ybWF0aW9uQ29udGV4dCBjb250ZXh0CgoJCW5ldyhUcmFuc2Zvcm1hdGlvbkNvbnRleHQgY29udGV4dCkgewoJCQl0aGlzLmNvbnRleHQgPSBjb250ZXh0CgkJfQoKCQlkZWYgZ2V0RmluYWxGaWVsZHMoTXV0YWJsZVR5cGVEZWNsYXJhdGlvbiBpdCkgewoJCQlkZWNsYXJlZEZpZWxkcy5maWx0ZXJbIXN0YXRpYyAmJiBmaW5hbCA9PSB0cnVlICYmIGluaXRpYWxpemVyID09PSBudWxsICYmIHRoZVByaW1hcnlHZW5lcmF0ZWRKYXZhRWxlbWVudF0KCQl9CgoJCWRlZiBuZWVkc0ZpbmFsRmllbGRDb25zdHJ1Y3RvcihNdXRhYmxlQ2xhc3NEZWNsYXJhdGlvbiBpdCkgewoJCQkhaGFzRmluYWxGaWVsZHNDb25zdHJ1Y3RvcgoJCQkmJiAocHJpbWFyeVNvdXJjZUVsZW1lbnQgYXMgQ2xhc3NEZWNsYXJhdGlvbikuZGVjbGFyZWRDb25zdHJ1Y3RvcnMuaXNFbXB0eQoJCX0KCgkJZGVmIGhhc0ZpbmFsRmllbGRzQ29uc3RydWN0b3IoTXV0YWJsZVR5cGVEZWNsYXJhdGlvbiBjbHMpIHsKCQkJdmFsIGV4cGVjdGVkVHlwZXMgPSBjbHMuZmluYWxGaWVsZHNDb25zdHJ1Y3RvckFyZ3VtZW50VHlwZXMKCQkJY2xzLmRlY2xhcmVkQ29uc3RydWN0b3JzLmV4aXN0cyBbCgkJCQlwYXJhbWV0ZXJzLm1hcFt0eXBlXS50b0xpc3QgPT0gZXhwZWN0ZWRUeXBlcwoJCQldCgkJfQoJCQoJCWRlZiBnZXRGaW5hbEZpZWxkc0NvbnN0cnVjdG9yQXJndW1lbnRUeXBlcyhNdXRhYmxlVHlwZURlY2xhcmF0aW9uIGNscykgewoJCQl2YWwgdHlwZXMgPSBuZXdBcnJheUxpc3QKCQkJaWYgKGNscy5zdXBlckNvbnN0cnVjdG9yICE9PSBudWxsKSB7CgkJCQl0eXBlcyArPSBjbHMuc3VwZXJDb25zdHJ1Y3Rvci5yZXNvbHZlZFBhcmFtZXRlcnMubWFwW3Jlc29sdmVkVHlwZV0KCQkJfQoJCQl0eXBlcyArPSBjbHMuZmluYWxGaWVsZHMubWFwW3R5cGVdCgkJCXR5cGVzCgkJfQoJCQoJCWRlZiBTdHJpbmcgZ2V0Q29uc3RydWN0b3JBbHJlYWR5RXhpc3RzTWVzc2FnZShNdXRhYmxlVHlwZURlY2xhcmF0aW9uIGl0KSB7CgkJCScnJ0Nhbm5vdCBjcmVhdGUgRmluYWxGaWVsZHNDb25zdHJ1Y3RvciBhcyBhIGNvbnN0cnVjdG9yIHdpdGggdGhlIHNpZ25hdHVyZSAibmV3KKtmaW5hbEZpZWxkc0NvbnN0cnVjdG9yQXJndW1lbnRUeXBlcy5qb2luKCIsIim7KSIgYWxyZWFkeSBleGlzdHMuJycnCgkJfQoKCQlkZWYgYWRkRmluYWxGaWVsZHNDb25zdHJ1Y3RvcihNdXRhYmxlQ2xhc3NEZWNsYXJhdGlvbiBpdCkgewoJCQlpZiAoZmluYWxGaWVsZHNDb25zdHJ1Y3RvckFyZ3VtZW50VHlwZXMuZW1wdHkpIHsKCQkJCXZhbCBhbm5vID0gZmluZEFubm90YXRpb24oRmluYWxGaWVsZHNDb25zdHJ1Y3Rvci5maW5kVHlwZUdsb2JhbGx5KQoJCQkJYW5uby5hZGRXYXJuaW5nKCcnJ1RoZXJlIGFyZSBubyBmaW5hbCBmaWVsZHMsIHRoaXMgYW5ub3RhdGlvbiBoYXMgbm8gZWZmZWN0JycnKQoJCQkJcmV0dXJuCgkJCX0KCQkJaWYgKGhhc0ZpbmFsRmllbGRzQ29uc3RydWN0b3IpIHsKCQkJCWFkZEVycm9yKGNvbnN0cnVjdG9yQWxyZWFkeUV4aXN0c01lc3NhZ2UpCgkJCQlyZXR1cm4KCQkJfQoJCQlhZGRDb25zdHJ1Y3RvciBbCgkJCQlwcmltYXJ5U291cmNlRWxlbWVudCA9IGRlY2xhcmluZ1R5cGUucHJpbWFyeVNvdXJjZUVsZW1lbnQKCQkJCW1ha2VGaW5hbEZpZWxkc0NvbnN0cnVjdG9yCgkJCV0KCQl9CgkJCgkJc3RhdGljIHZhbCBFTVBUWV9CT0RZID0gUGF0dGVybi5jb21waWxlKCIoXFx7KFxccypcXH0pPyk/IikKCgkJZGVmIG1ha2VGaW5hbEZpZWxkc0NvbnN0cnVjdG9yKE11dGFibGVDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIGl0KSB7CgkJCWlmIChkZWNsYXJpbmdUeXBlLmZpbmFsRmllbGRzQ29uc3RydWN0b3JBcmd1bWVudFR5cGVzLmVtcHR5KSB7CgkJCQl2YWwgYW5ubyA9IGZpbmRBbm5vdGF0aW9uKEZpbmFsRmllbGRzQ29uc3RydWN0b3IuZmluZFR5cGVHbG9iYWxseSkKCQkJCWFubm8uYWRkV2FybmluZygnJydUaGVyZSBhcmUgbm8gZmluYWwgZmllbGRzLCB0aGlzIGFubm90YXRpb24gaGFzIG5vIGVmZmVjdCcnJykKCQkJCXJldHVybgoJCQl9CgkJCWlmIChkZWNsYXJpbmdUeXBlLmhhc0ZpbmFsRmllbGRzQ29uc3RydWN0b3IpIHsKCQkJCWFkZEVycm9yKGRlY2xhcmluZ1R5cGUuY29uc3RydWN0b3JBbHJlYWR5RXhpc3RzTWVzc2FnZSkKCQkJCXJldHVybgoJCQl9CgkJCWlmICghcGFyYW1ldGVycy5lbXB0eSkgewoJCQkJYWRkRXJyb3IoIlBhcmFtZXRlciBsaXN0IG11c3QgYmUgZW1wdHkiKQoJCQl9CgkJCWlmIChib2R5ICE9PSBudWxsICYmICFFTVBUWV9CT0RZLm1hdGNoZXIoYm9keS50b1N0cmluZykubWF0Y2hlcykgewoJCQkJYWRkRXJyb3IoIkJvZHkgbXVzdCBiZSBlbXB0eSIpCgkJCX0KCQkJdmFsIHN1cGVyUGFyYW1ldGVycyA9IGRlY2xhcmluZ1R5cGUuc3VwZXJDb25zdHJ1Y3Rvcj8ucmVzb2x2ZWRQYXJhbWV0ZXJzID86ICNbXQoJCQlzdXBlclBhcmFtZXRlcnMuZm9yRWFjaCBbIHAgfAoJCQkJYWRkUGFyYW1ldGVyKHAuZGVjbGFyYXRpb24uc2ltcGxlTmFtZSwgcC5yZXNvbHZlZFR5cGUpCgkJCV0KCQkJdmFsIGZpZWxkVG9QYXJhbWV0ZXIgPSBuZXdIYXNoTWFwCgkJCWRlY2xhcmluZ1R5cGUuZmluYWxGaWVsZHMuZm9yRWFjaCBbIHAgfAoJCQkJcC5tYXJrQXNJbml0aWFsaXplZEJ5KGl0KQoJCQkJdmFsIHBhcmFtID0gYWRkUGFyYW1ldGVyKHAuc2ltcGxlTmFtZSwgcC50eXBlLm9yT2JqZWN0KQoJCQkJZmllbGRUb1BhcmFtZXRlci5wdXQocCwgcGFyYW0pCgkJCV0KCQkJYm9keSA9ICcnJwoJCQkJc3VwZXIoq3N1cGVyUGFyYW1ldGVycy5qb2luKCIsICIpW2RlY2xhcmF0aW9uLnNpbXBsZU5hbWVduyk7CgkJCQmrRk9SIGFyZyA6IGRlY2xhcmluZ1R5cGUuZmluYWxGaWVsZHO7CgkJCQkJdGhpcy6rYXJnLnNpbXBsZU5hbWW7ID0gq2ZpZWxkVG9QYXJhbWV0ZXIuZ2V0KGFyZykuc2ltcGxlTmFtZbs7CgkJCQmrRU5ERk9SuwoJCQknJycKCQl9CgoJCWRlZiBnZXRTdXBlckNvbnN0cnVjdG9yKFR5cGVEZWNsYXJhdGlvbiBpdCkgewoJCQlpZiAoaXQgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uKSB7CgkJCQlpZiAoZXh0ZW5kZWRDbGFzcyA9PSBvYmplY3QgfHwgZXh0ZW5kZWRDbGFzcyA9PT0gbnVsbCkKCQkJCQlyZXR1cm4gbnVsbDsKCQkJCXJldHVybiBleHRlbmRlZENsYXNzLmRlY2xhcmVkUmVzb2x2ZWRDb25zdHJ1Y3RvcnMuaGVhZAoJCQl9IGVsc2UgewoJCQkJcmV0dXJuIG51bGwKCQkJfQoJCX0KCQkKCQlwcml2YXRlIGRlZiBvck9iamVjdChUeXBlUmVmZXJlbmNlIHJlZikgewoJCQlpZiAocmVmID09PSBudWxsKSBvYmplY3QgZWxzZSByZWYKCQl9Cgl9Cn0K