UEsDBBQAAAAAAFl2J0gUVak0qAIAAKgCAAAkAAAAaW8vdi9tb2pvL2Rpc2NvdmVyeS9TY2FuSGFuZGxlci5qYXZhLy8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIFRoaXMgZmlsZSBpcyBhdXRvZ2VuZXJhdGVkIGJ5OgovLyAgICAgbW9qby9wdWJsaWMvdG9vbHMvYmluZGluZ3MvbW9qb21fYmluZGluZ3NfZ2VuZXJhdG9yLnB5Ci8vIEZvcjoKLy8gICAgIG1vam9tL3ZhbmFkaXVtL2Rpc2NvdmVyeS5tb2pvbQovLwoKcGFja2FnZSBpby52Lm1vam8uZGlzY292ZXJ5OwoKcHVibGljIGludGVyZmFjZSBTY2FuSGFuZGxlciBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkludGVyZmFjZSB7CgogICAgcHVibGljIGludGVyZmFjZSBQcm94eSBleHRlbmRzIFNjYW5IYW5kbGVyLCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2UuUHJveHkgewogICAgfQoKICAgIE5hbWVkTWFuYWdlcjxTY2FuSGFuZGxlciwgU2NhbkhhbmRsZXIuUHJveHk+IE1BTkFHRVIgPSBTY2FuSGFuZGxlcl9JbnRlcm5hbC5NQU5BR0VSOwoKICAgIHZvaWQgZm91bmQoU2VydmljZSBzZXJ2aWNlKTsKCiAgICB2b2lkIGxvc3QoU3RyaW5nIGluc3RhbmNlSWQpOwp9CgpQSwMEFAAAAAAAWXYnSHjxoujBKwAAwSsAAC0AAABpby92L21vam8vZGlzY292ZXJ5L1NjYW5IYW5kbGVyX0ludGVybmFsLmphdmEvLyBDb3B5cmlnaHQgMjAxNCBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gVGhpcyBmaWxlIGlzIGF1dG9nZW5lcmF0ZWQgYnk6Ci8vICAgICBtb2pvL3B1YmxpYy90b29scy9iaW5kaW5ncy9tb2pvbV9iaW5kaW5nc19nZW5lcmF0b3IucHkKLy8gRm9yOgovLyAgICAgbW9qb20vdmFuYWRpdW0vZGlzY292ZXJ5Lm1vam9tCi8vCgpwYWNrYWdlIGlvLnYubW9qby5kaXNjb3Zlcnk7CgpjbGFzcyBTY2FuSGFuZGxlcl9JbnRlcm5hbCB7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2UuTmFtZWRNYW5hZ2VyPFNjYW5IYW5kbGVyLCBTY2FuSGFuZGxlci5Qcm94eT4gTUFOQUdFUiA9CiAgICAgICAgICAgIG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2UuTmFtZWRNYW5hZ2VyPFNjYW5IYW5kbGVyLCBTY2FuSGFuZGxlci5Qcm94eT4oKSB7CiAgICAKICAgICAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiAidjIzOjpkaXNjb3Zlcnk6OlNjYW5IYW5kbGVyIjsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgaW50IGdldFZlcnNpb24oKSB7CiAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgUHJveHkgYnVpbGRQcm94eShvcmcuY2hyb21pdW0ubW9qby5zeXN0ZW0uQ29yZSBjb3JlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VSZWNlaXZlcldpdGhSZXNwb25kZXIgbWVzc2FnZVJlY2VpdmVyKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgUHJveHkoY29yZSwgbWVzc2FnZVJlY2VpdmVyKTsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgU3R1YiBidWlsZFN0dWIob3JnLmNocm9taXVtLm1vam8uc3lzdGVtLkNvcmUgY29yZSwgU2NhbkhhbmRsZXIgaW1wbCkgewogICAgICAgICAgICByZXR1cm4gbmV3IFN0dWIoY29yZSwgaW1wbCk7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFNjYW5IYW5kbGVyW10gYnVpbGRBcnJheShpbnQgc2l6ZSkgewogICAgICAgICAgcmV0dXJuIG5ldyBTY2FuSGFuZGxlcltzaXplXTsKICAgICAgICB9CiAgICB9OwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGT1VORF9PUkRJTkFMID0gMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBMT1NUX09SRElOQUwgPSAxOwoKICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm94eSBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkludGVyZmFjZS5BYnN0cmFjdFByb3h5IGltcGxlbWVudHMgU2NhbkhhbmRsZXIuUHJveHkgewoKICAgICAgICBQcm94eShvcmcuY2hyb21pdW0ubW9qby5zeXN0ZW0uQ29yZSBjb3JlLAogICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VSZWNlaXZlcldpdGhSZXNwb25kZXIgbWVzc2FnZVJlY2VpdmVyKSB7CiAgICAgICAgICAgIHN1cGVyKGNvcmUsIG1lc3NhZ2VSZWNlaXZlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBmb3VuZChTZXJ2aWNlIHNlcnZpY2UpIHsKICAgICAgICAgICAgU2NhbkhhbmRsZXJGb3VuZFBhcmFtcyBfbWVzc2FnZSA9IG5ldyBTY2FuSGFuZGxlckZvdW5kUGFyYW1zKCk7CiAgICAgICAgICAgIF9tZXNzYWdlLnNlcnZpY2UgPSBzZXJ2aWNlOwogICAgICAgICAgICBnZXRQcm94eUhhbmRsZXIoKS5nZXRNZXNzYWdlUmVjZWl2ZXIoKS5hY2NlcHQoCiAgICAgICAgICAgICAgICAgICAgX21lc3NhZ2Uuc2VyaWFsaXplV2l0aEhlYWRlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByb3h5SGFuZGxlcigpLmdldENvcmUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyKEZPVU5EX09SRElOQUwpKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBsb3N0KFN0cmluZyBpbnN0YW5jZUlkKSB7CiAgICAgICAgICAgIFNjYW5IYW5kbGVyTG9zdFBhcmFtcyBfbWVzc2FnZSA9IG5ldyBTY2FuSGFuZGxlckxvc3RQYXJhbXMoKTsKICAgICAgICAgICAgX21lc3NhZ2UuaW5zdGFuY2VJZCA9IGluc3RhbmNlSWQ7CiAgICAgICAgICAgIGdldFByb3h5SGFuZGxlcigpLmdldE1lc3NhZ2VSZWNlaXZlcigpLmFjY2VwdCgKICAgICAgICAgICAgICAgICAgICBfbWVzc2FnZS5zZXJpYWxpemVXaXRoSGVhZGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0UHJveHlIYW5kbGVyKCkuZ2V0Q29yZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIoTE9TVF9PUkRJTkFMKSkpOwogICAgICAgIH0KCiAgICB9CgogICAgc3RhdGljIGZpbmFsIGNsYXNzIFN0dWIgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2UuU3R1YjxTY2FuSGFuZGxlcj4gewoKICAgICAgICBTdHViKG9yZy5jaHJvbWl1bS5tb2pvLnN5c3RlbS5Db3JlIGNvcmUsIFNjYW5IYW5kbGVyIGltcGwpIHsKICAgICAgICAgICAgc3VwZXIoY29yZSwgaW1wbCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHQob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TZXJ2aWNlTWVzc2FnZSBtZXNzYWdlV2l0aEhlYWRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXNTZXJ2aWNlTWVzc2FnZSgpOwogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlciBoZWFkZXIgPSBtZXNzYWdlV2l0aEhlYWRlci5nZXRIZWFkZXIoKTsKICAgICAgICAgICAgICAgIGlmICghaGVhZGVyLnZhbGlkYXRlSGVhZGVyKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIuTk9fRkxBRykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzd2l0Y2goaGVhZGVyLmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2Ugb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlQ29udHJvbE1lc3NhZ2VzQ29uc3RhbnRzLlJVTl9PUl9DTE9TRV9QSVBFX01FU1NBR0VfSUQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2VDb250cm9sTWVzc2FnZXNIZWxwZXIuaGFuZGxlUnVuT3JDbG9zZVBpcGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2NhbkhhbmRsZXJfSW50ZXJuYWwuTUFOQUdFUiwgbWVzc2FnZVdpdGhIZWFkZXIpOwogICAgICAgICAgICAgICAgICAgIGNhc2UgRk9VTkRfT1JESU5BTDogewogICAgICAgICAgICAgICAgICAgICAgICBTY2FuSGFuZGxlckZvdW5kUGFyYW1zIGRhdGEgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNjYW5IYW5kbGVyRm91bmRQYXJhbXMuZGVzZXJpYWxpemUobWVzc2FnZVdpdGhIZWFkZXIuZ2V0UGF5bG9hZCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2V0SW1wbCgpLmZvdW5kKGRhdGEuc2VydmljZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXNlIExPU1RfT1JESU5BTDogewogICAgICAgICAgICAgICAgICAgICAgICBTY2FuSGFuZGxlckxvc3RQYXJhbXMgZGF0YSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2NhbkhhbmRsZXJMb3N0UGFyYW1zLmRlc2VyaWFsaXplKG1lc3NhZ2VXaXRoSGVhZGVyLmdldFBheWxvYWQoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGdldEltcGwoKS5sb3N0KGRhdGEuaW5zdGFuY2VJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0V2l0aFJlc3BvbmRlcihvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlIG1lc3NhZ2UsIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VSZWNlaXZlciByZWNlaXZlcikgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuU2VydmljZU1lc3NhZ2UgbWVzc2FnZVdpdGhIZWFkZXIgPQogICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmFzU2VydmljZU1lc3NhZ2UoKTsKICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIgaGVhZGVyID0gbWVzc2FnZVdpdGhIZWFkZXIuZ2V0SGVhZGVyKCk7CiAgICAgICAgICAgICAgICBpZiAoIWhlYWRlci52YWxpZGF0ZUhlYWRlcihvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyLk1FU1NBR0VfRVhQRUNUU19SRVNQT05TRV9GTEFHKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN3aXRjaChoZWFkZXIuZ2V0VHlwZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2VDb250cm9sTWVzc2FnZXNDb25zdGFudHMuUlVOX01FU1NBR0VfSUQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2VDb250cm9sTWVzc2FnZXNIZWxwZXIuaGFuZGxlUnVuKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldENvcmUoKSwgU2NhbkhhbmRsZXJfSW50ZXJuYWwuTUFOQUdFUiwgbWVzc2FnZVdpdGhIZWFkZXIsIHJlY2VpdmVyKTsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gY2F0Y2ggKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oZS50b1N0cmluZygpKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgZmluYWwgY2xhc3MgU2NhbkhhbmRsZXJGb3VuZFBhcmFtcyBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlN0cnVjdCB7CiAgICAKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU1RSVUNUX1NJWkUgPSAxNjsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyW10gVkVSU0lPTl9BUlJBWSA9IG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyW10ge25ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyKDE2LCAwKX07CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBERUZBVUxUX1NUUlVDVF9JTkZPID0gVkVSU0lPTl9BUlJBWVswXTsKICAgIAogICAgICAgIHB1YmxpYyBTZXJ2aWNlIHNlcnZpY2U7CiAgICAKICAgICAgICBwcml2YXRlIFNjYW5IYW5kbGVyRm91bmRQYXJhbXMoaW50IHZlcnNpb24pIHsKICAgICAgICAgICAgc3VwZXIoU1RSVUNUX1NJWkUsIHZlcnNpb24pOwogICAgICAgIH0KICAgIAogICAgICAgIHB1YmxpYyBTY2FuSGFuZGxlckZvdW5kUGFyYW1zKCkgewogICAgICAgICAgICB0aGlzKDApOwogICAgICAgIH0KICAgIAogICAgICAgIHB1YmxpYyBzdGF0aWMgU2NhbkhhbmRsZXJGb3VuZFBhcmFtcyBkZXNlcmlhbGl6ZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlIG1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIGRlY29kZShuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlcihtZXNzYWdlKSk7CiAgICAgICAgfQogICAgCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgcHVibGljIHN0YXRpYyBTY2FuSGFuZGxlckZvdW5kUGFyYW1zIGRlY29kZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyIGRlY29kZXIwKSB7CiAgICAgICAgICAgIGlmIChkZWNvZGVyMCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyIG1haW5EYXRhSGVhZGVyID0gZGVjb2RlcjAucmVhZEFuZFZhbGlkYXRlRGF0YUhlYWRlcihWRVJTSU9OX0FSUkFZKTsKICAgICAgICAgICAgU2NhbkhhbmRsZXJGb3VuZFBhcmFtcyByZXN1bHQgPSBuZXcgU2NhbkhhbmRsZXJGb3VuZFBhcmFtcyhtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbik7CiAgICAgICAgICAgIGlmIChtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbiA+PSAwKSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyIGRlY29kZXIxID0gZGVjb2RlcjAucmVhZFBvaW50ZXIoOCwgZmFsc2UpOwogICAgICAgICAgICAgICAgcmVzdWx0LnNlcnZpY2UgPSBTZXJ2aWNlLmRlY29kZShkZWNvZGVyMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyKSB7CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcjAgPSBlbmNvZGVyLmdldEVuY29kZXJBdERhdGFPZmZzZXQoREVGQVVMVF9TVFJVQ1RfSU5GTyk7CiAgICAgICAgICAgIGVuY29kZXIwLmVuY29kZShzZXJ2aWNlLCA4LCBmYWxzZSk7CiAgICAgICAgfQogICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBPYmplY3QjZXF1YWxzKE9iamVjdCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgewogICAgICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmplY3QuZ2V0Q2xhc3MoKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgU2NhbkhhbmRsZXJGb3VuZFBhcmFtcyBvdGhlciA9IChTY2FuSGFuZGxlckZvdW5kUGFyYW1zKSBvYmplY3Q7CiAgICAgICAgICAgIGlmICghb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuZXF1YWxzKHRoaXMuc2VydmljZSwgb3RoZXIuc2VydmljZSkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIAogICAgICAgIC8qKgogICAgICAgICAqIEBzZWUgT2JqZWN0I2hhc2hDb2RlKCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICBmaW5hbCBpbnQgcHJpbWUgPSAzMTsKICAgICAgICAgICAgaW50IHJlc3VsdCA9IHByaW1lICsgZ2V0Q2xhc3MoKS5oYXNoQ29kZSgpOwogICAgICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKHNlcnZpY2UpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgZmluYWwgY2xhc3MgU2NhbkhhbmRsZXJMb3N0UGFyYW1zIGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuU3RydWN0IHsKICAgIAogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVFJVQ1RfU0laRSA9IDE2OwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXJbXSBWRVJTSU9OX0FSUkFZID0gbmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXJbXSB7bmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIoMTYsIDApfTsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyIERFRkFVTFRfU1RSVUNUX0lORk8gPSBWRVJTSU9OX0FSUkFZWzBdOwogICAgCiAgICAgICAgcHVibGljIFN0cmluZyBpbnN0YW5jZUlkOwogICAgCiAgICAgICAgcHJpdmF0ZSBTY2FuSGFuZGxlckxvc3RQYXJhbXMoaW50IHZlcnNpb24pIHsKICAgICAgICAgICAgc3VwZXIoU1RSVUNUX1NJWkUsIHZlcnNpb24pOwogICAgICAgIH0KICAgIAogICAgICAgIHB1YmxpYyBTY2FuSGFuZGxlckxvc3RQYXJhbXMoKSB7CiAgICAgICAgICAgIHRoaXMoMCk7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIHN0YXRpYyBTY2FuSGFuZGxlckxvc3RQYXJhbXMgZGVzZXJpYWxpemUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBkZWNvZGUobmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIobWVzc2FnZSkpOwogICAgICAgIH0KICAgIAogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIHB1YmxpYyBzdGF0aWMgU2NhbkhhbmRsZXJMb3N0UGFyYW1zIGRlY29kZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyIGRlY29kZXIwKSB7CiAgICAgICAgICAgIGlmIChkZWNvZGVyMCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyIG1haW5EYXRhSGVhZGVyID0gZGVjb2RlcjAucmVhZEFuZFZhbGlkYXRlRGF0YUhlYWRlcihWRVJTSU9OX0FSUkFZKTsKICAgICAgICAgICAgU2NhbkhhbmRsZXJMb3N0UGFyYW1zIHJlc3VsdCA9IG5ldyBTY2FuSGFuZGxlckxvc3RQYXJhbXMobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24pOwogICAgICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICAgICAgcmVzdWx0Lmluc3RhbmNlSWQgPSBkZWNvZGVyMC5yZWFkU3RyaW5nKDgsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgIAogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGVuY29kZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIpIHsKICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyMCA9IGVuY29kZXIuZ2V0RW5jb2RlckF0RGF0YU9mZnNldChERUZBVUxUX1NUUlVDVF9JTkZPKTsKICAgICAgICAgICAgZW5jb2RlcjAuZW5jb2RlKGluc3RhbmNlSWQsIDgsIGZhbHNlKTsKICAgICAgICB9CiAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIE9iamVjdCNlcXVhbHMoT2JqZWN0KQogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CiAgICAgICAgICAgIGlmIChvYmplY3QgPT0gdGhpcykKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmIChnZXRDbGFzcygpICE9IG9iamVjdC5nZXRDbGFzcygpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBTY2FuSGFuZGxlckxvc3RQYXJhbXMgb3RoZXIgPSAoU2NhbkhhbmRsZXJMb3N0UGFyYW1zKSBvYmplY3Q7CiAgICAgICAgICAgIGlmICghb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuZXF1YWxzKHRoaXMuaW5zdGFuY2VJZCwgb3RoZXIuaW5zdGFuY2VJZCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIAogICAgICAgIC8qKgogICAgICAgICAqIEBzZWUgT2JqZWN0I2hhc2hDb2RlKCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICBmaW5hbCBpbnQgcHJpbWUgPSAzMTsKICAgICAgICAgICAgaW50IHJlc3VsdCA9IHByaW1lICsgZ2V0Q2xhc3MoKS5oYXNoQ29kZSgpOwogICAgICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGluc3RhbmNlSWQpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgIH0KCn0KClBLAwQUAAAAAABZdidINGRBhuoMAADqDAAAHgAAAGlvL3YvbW9qby9kaXNjb3ZlcnkvRXJyb3IuamF2YS8vIENvcHlyaWdodCAyMDE0IFRoZSBDaHJvbWl1bSBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlCi8vIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuCgovLyBUaGlzIGZpbGUgaXMgYXV0b2dlbmVyYXRlZCBieToKLy8gICAgIG1vam8vcHVibGljL3Rvb2xzL2JpbmRpbmdzL21vam9tX2JpbmRpbmdzX2dlbmVyYXRvci5weQovLyBGb3I6Ci8vICAgICBtb2pvbS92YW5hZGl1bS9kaXNjb3ZlcnkubW9qb20KLy8KCnBhY2thZ2UgaW8udi5tb2pvLmRpc2NvdmVyeTsKCnB1YmxpYyBmaW5hbCBjbGFzcyBFcnJvciBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlN0cnVjdCB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNUUlVDVF9TSVpFID0gMzI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyW10gVkVSU0lPTl9BUlJBWSA9IG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyW10ge25ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyKDMyLCAwKX07CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyIERFRkFVTFRfU1RSVUNUX0lORk8gPSBWRVJTSU9OX0FSUkFZWzBdOwoKICAgIHB1YmxpYyBTdHJpbmcgaWQ7CiAgICBwdWJsaWMgaW50IGFjdGlvbjsKICAgIHB1YmxpYyBTdHJpbmcgbXNnOwoKICAgIHByaXZhdGUgRXJyb3IoaW50IHZlcnNpb24pIHsKICAgICAgICBzdXBlcihTVFJVQ1RfU0laRSwgdmVyc2lvbik7CiAgICB9CgogICAgcHVibGljIEVycm9yKCkgewogICAgICAgIHRoaXMoMCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBFcnJvciBkZXNlcmlhbGl6ZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlIG1lc3NhZ2UpIHsKICAgICAgICByZXR1cm4gZGVjb2RlKG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyKG1lc3NhZ2UpKTsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgIHB1YmxpYyBzdGF0aWMgRXJyb3IgZGVjb2RlKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIgZGVjb2RlcjApIHsKICAgICAgICBpZiAoZGVjb2RlcjAgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBtYWluRGF0YUhlYWRlciA9IGRlY29kZXIwLnJlYWRBbmRWYWxpZGF0ZURhdGFIZWFkZXIoVkVSU0lPTl9BUlJBWSk7CiAgICAgICAgRXJyb3IgcmVzdWx0ID0gbmV3IEVycm9yKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uKTsKICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICByZXN1bHQuaWQgPSBkZWNvZGVyMC5yZWFkU3RyaW5nKDgsIGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uID49IDApIHsKICAgICAgICAgICAgcmVzdWx0LmFjdGlvbiA9IGRlY29kZXIwLnJlYWRJbnQoMTYpOwogICAgICAgIH0KICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICByZXN1bHQubXNnID0gZGVjb2RlcjAucmVhZFN0cmluZygyNCwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgQE92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyKSB7CiAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyMCA9IGVuY29kZXIuZ2V0RW5jb2RlckF0RGF0YU9mZnNldChERUZBVUxUX1NUUlVDVF9JTkZPKTsKICAgICAgICBlbmNvZGVyMC5lbmNvZGUoaWQsIDgsIGZhbHNlKTsKICAgICAgICBlbmNvZGVyMC5lbmNvZGUoYWN0aW9uLCAxNik7CiAgICAgICAgZW5jb2RlcjAuZW5jb2RlKG1zZywgMjQsIGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgT2JqZWN0I2VxdWFscyhPYmplY3QpCiAgICAgKi8KICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChnZXRDbGFzcygpICE9IG9iamVjdC5nZXRDbGFzcygpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgRXJyb3Igb3RoZXIgPSAoRXJyb3IpIG9iamVjdDsKICAgICAgICBpZiAoIW9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmVxdWFscyh0aGlzLmlkLCBvdGhlci5pZCkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAodGhpcy5hY3Rpb24gIT0gb3RoZXIuYWN0aW9uKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5lcXVhbHModGhpcy5tc2csIG90aGVyLm1zZykpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgT2JqZWN0I2hhc2hDb2RlKCkKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGZpbmFsIGludCBwcmltZSA9IDMxOwogICAgICAgIGludCByZXN1bHQgPSBwcmltZSArIGdldENsYXNzKCkuaGFzaENvZGUoKTsKICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGlkKTsKICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGFjdGlvbik7CiAgICAgICAgcmVzdWx0ID0gcHJpbWUgKiByZXN1bHQgKyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5oYXNoQ29kZShtc2cpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9Cn0KClBLAwQUAAAAAABZdidI8LwSs3hjAAB4YwAALAAAAGlvL3YvbW9qby9kaXNjb3ZlcnkvQWR2ZXJ0aXNlcl9JbnRlcm5hbC5qYXZhLy8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIFRoaXMgZmlsZSBpcyBhdXRvZ2VuZXJhdGVkIGJ5OgovLyAgICAgbW9qby9wdWJsaWMvdG9vbHMvYmluZGluZ3MvbW9qb21fYmluZGluZ3NfZ2VuZXJhdG9yLnB5Ci8vIEZvcjoKLy8gICAgIG1vam9tL3ZhbmFkaXVtL2Rpc2NvdmVyeS5tb2pvbQovLwoKcGFja2FnZSBpby52Lm1vam8uZGlzY292ZXJ5OwoKY2xhc3MgQWR2ZXJ0aXNlcl9JbnRlcm5hbCB7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2UuTmFtZWRNYW5hZ2VyPEFkdmVydGlzZXIsIEFkdmVydGlzZXIuUHJveHk+IE1BTkFHRVIgPQogICAgICAgICAgICBuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlLk5hbWVkTWFuYWdlcjxBZHZlcnRpc2VyLCBBZHZlcnRpc2VyLlByb3h5PigpIHsKICAgIAogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuICJ2MjM6OmRpc2NvdmVyeTo6QWR2ZXJ0aXNlciI7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIGludCBnZXRWZXJzaW9uKCkgewogICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFByb3h5IGJ1aWxkUHJveHkob3JnLmNocm9taXVtLm1vam8uc3lzdGVtLkNvcmUgY29yZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlUmVjZWl2ZXJXaXRoUmVzcG9uZGVyIG1lc3NhZ2VSZWNlaXZlcikgewogICAgICAgICAgICByZXR1cm4gbmV3IFByb3h5KGNvcmUsIG1lc3NhZ2VSZWNlaXZlcik7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFN0dWIgYnVpbGRTdHViKG9yZy5jaHJvbWl1bS5tb2pvLnN5c3RlbS5Db3JlIGNvcmUsIEFkdmVydGlzZXIgaW1wbCkgewogICAgICAgICAgICByZXR1cm4gbmV3IFN0dWIoY29yZSwgaW1wbCk7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIEFkdmVydGlzZXJbXSBidWlsZEFycmF5KGludCBzaXplKSB7CiAgICAgICAgICByZXR1cm4gbmV3IEFkdmVydGlzZXJbc2l6ZV07CiAgICAgICAgfQogICAgfTsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQURWRVJUSVNFX09SRElOQUwgPSAwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNUT1BfT1JESU5BTCA9IDE7CgogICAgc3RhdGljIGZpbmFsIGNsYXNzIFByb3h5IGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlLkFic3RyYWN0UHJveHkgaW1wbGVtZW50cyBBZHZlcnRpc2VyLlByb3h5IHsKCiAgICAgICAgUHJveHkob3JnLmNocm9taXVtLm1vam8uc3lzdGVtLkNvcmUgY29yZSwKICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlUmVjZWl2ZXJXaXRoUmVzcG9uZGVyIG1lc3NhZ2VSZWNlaXZlcikgewogICAgICAgICAgICBzdXBlcihjb3JlLCBtZXNzYWdlUmVjZWl2ZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgYWR2ZXJ0aXNlKFNlcnZpY2Ugc2VydmljZSwgU3RyaW5nW10gdmlzaWJpbGl0eSwgQWR2ZXJ0aXNlUmVzcG9uc2UgY2FsbGJhY2spIHsKICAgICAgICAgICAgQWR2ZXJ0aXNlckFkdmVydGlzZVBhcmFtcyBfbWVzc2FnZSA9IG5ldyBBZHZlcnRpc2VyQWR2ZXJ0aXNlUGFyYW1zKCk7CiAgICAgICAgICAgIF9tZXNzYWdlLnNlcnZpY2UgPSBzZXJ2aWNlOwogICAgICAgICAgICBfbWVzc2FnZS52aXNpYmlsaXR5ID0gdmlzaWJpbGl0eTsKICAgICAgICAgICAgZ2V0UHJveHlIYW5kbGVyKCkuZ2V0TWVzc2FnZVJlY2VpdmVyKCkuYWNjZXB0V2l0aFJlc3BvbmRlcigKICAgICAgICAgICAgICAgICAgICBfbWVzc2FnZS5zZXJpYWxpemVXaXRoSGVhZGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0UHJveHlIYW5kbGVyKCkuZ2V0Q29yZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFEVkVSVElTRV9PUkRJTkFMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyLk1FU1NBR0VfRVhQRUNUU19SRVNQT05TRV9GTEFHLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKSksCiAgICAgICAgICAgICAgICAgICAgbmV3IEFkdmVydGlzZXJBZHZlcnRpc2VSZXNwb25zZVBhcmFtc0ZvcndhcmRUb0NhbGxiYWNrKGNhbGxiYWNrKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBzdG9wKGludCBoLCBTdG9wUmVzcG9uc2UgY2FsbGJhY2spIHsKICAgICAgICAgICAgQWR2ZXJ0aXNlclN0b3BQYXJhbXMgX21lc3NhZ2UgPSBuZXcgQWR2ZXJ0aXNlclN0b3BQYXJhbXMoKTsKICAgICAgICAgICAgX21lc3NhZ2UuaCA9IGg7CiAgICAgICAgICAgIGdldFByb3h5SGFuZGxlcigpLmdldE1lc3NhZ2VSZWNlaXZlcigpLmFjY2VwdFdpdGhSZXNwb25kZXIoCiAgICAgICAgICAgICAgICAgICAgX21lc3NhZ2Uuc2VyaWFsaXplV2l0aEhlYWRlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByb3h5SGFuZGxlcigpLmdldENvcmUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVE9QX09SRElOQUwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIuTUVTU0FHRV9FWFBFQ1RTX1JFU1BPTlNFX0ZMQUcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApKSwKICAgICAgICAgICAgICAgICAgICBuZXcgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtc0ZvcndhcmRUb0NhbGxiYWNrKGNhbGxiYWNrKSk7CiAgICAgICAgfQoKICAgIH0KCiAgICBzdGF0aWMgZmluYWwgY2xhc3MgU3R1YiBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkludGVyZmFjZS5TdHViPEFkdmVydGlzZXI+IHsKCiAgICAgICAgU3R1YihvcmcuY2hyb21pdW0ubW9qby5zeXN0ZW0uQ29yZSBjb3JlLCBBZHZlcnRpc2VyIGltcGwpIHsKICAgICAgICAgICAgc3VwZXIoY29yZSwgaW1wbCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHQob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TZXJ2aWNlTWVzc2FnZSBtZXNzYWdlV2l0aEhlYWRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXNTZXJ2aWNlTWVzc2FnZSgpOwogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlciBoZWFkZXIgPSBtZXNzYWdlV2l0aEhlYWRlci5nZXRIZWFkZXIoKTsKICAgICAgICAgICAgICAgIGlmICghaGVhZGVyLnZhbGlkYXRlSGVhZGVyKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIuTk9fRkxBRykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzd2l0Y2goaGVhZGVyLmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2Ugb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlQ29udHJvbE1lc3NhZ2VzQ29uc3RhbnRzLlJVTl9PUl9DTE9TRV9QSVBFX01FU1NBR0VfSUQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2VDb250cm9sTWVzc2FnZXNIZWxwZXIuaGFuZGxlUnVuT3JDbG9zZVBpcGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWR2ZXJ0aXNlcl9JbnRlcm5hbC5NQU5BR0VSLCBtZXNzYWdlV2l0aEhlYWRlcik7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZXNlcmlhbGl6YXRpb25FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdFdpdGhSZXNwb25kZXIob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlLCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlUmVjZWl2ZXIgcmVjZWl2ZXIpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlNlcnZpY2VNZXNzYWdlIG1lc3NhZ2VXaXRoSGVhZGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hc1NlcnZpY2VNZXNzYWdlKCk7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyIGhlYWRlciA9IG1lc3NhZ2VXaXRoSGVhZGVyLmdldEhlYWRlcigpOwogICAgICAgICAgICAgICAgaWYgKCFoZWFkZXIudmFsaWRhdGVIZWFkZXIob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlci5NRVNTQUdFX0VYUEVDVFNfUkVTUE9OU0VfRkxBRykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzd2l0Y2goaGVhZGVyLmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2Ugb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlQ29udHJvbE1lc3NhZ2VzQ29uc3RhbnRzLlJVTl9NRVNTQUdFX0lEOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlQ29udHJvbE1lc3NhZ2VzSGVscGVyLmhhbmRsZVJ1bigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDb3JlKCksIEFkdmVydGlzZXJfSW50ZXJuYWwuTUFOQUdFUiwgbWVzc2FnZVdpdGhIZWFkZXIsIHJlY2VpdmVyKTsKICAgICAgICAgICAgICAgICAgICBjYXNlIEFEVkVSVElTRV9PUkRJTkFMOiB7CiAgICAgICAgICAgICAgICAgICAgICAgIEFkdmVydGlzZXJBZHZlcnRpc2VQYXJhbXMgZGF0YSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWR2ZXJ0aXNlckFkdmVydGlzZVBhcmFtcy5kZXNlcmlhbGl6ZShtZXNzYWdlV2l0aEhlYWRlci5nZXRQYXlsb2FkKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBnZXRJbXBsKCkuYWR2ZXJ0aXNlKGRhdGEuc2VydmljZSwgZGF0YS52aXNpYmlsaXR5LCBuZXcgQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zUHJveHlUb1Jlc3BvbmRlcihnZXRDb3JlKCksIHJlY2VpdmVyLCBoZWFkZXIuZ2V0UmVxdWVzdElkKCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhc2UgU1RPUF9PUkRJTkFMOiB7CiAgICAgICAgICAgICAgICAgICAgICAgIEFkdmVydGlzZXJTdG9wUGFyYW1zIGRhdGEgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkdmVydGlzZXJTdG9wUGFyYW1zLmRlc2VyaWFsaXplKG1lc3NhZ2VXaXRoSGVhZGVyLmdldFBheWxvYWQoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGdldEltcGwoKS5zdG9wKGRhdGEuaCwgbmV3IEFkdmVydGlzZXJTdG9wUmVzcG9uc2VQYXJhbXNQcm94eVRvUmVzcG9uZGVyKGdldENvcmUoKSwgcmVjZWl2ZXIsIGhlYWRlci5nZXRSZXF1ZXN0SWQoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZXNlcmlhbGl6YXRpb25FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGNsYXNzIEFkdmVydGlzZXJBZHZlcnRpc2VQYXJhbXMgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TdHJ1Y3QgewogICAgCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNUUlVDVF9TSVpFID0gMjQ7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIFZFUlNJT05fQVJSQVkgPSBuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIHtuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcigyNCwgMCl9OwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgREVGQVVMVF9TVFJVQ1RfSU5GTyA9IFZFUlNJT05fQVJSQVlbMF07CiAgICAKICAgICAgICBwdWJsaWMgU2VydmljZSBzZXJ2aWNlOwogICAgICAgIHB1YmxpYyBTdHJpbmdbXSB2aXNpYmlsaXR5OwogICAgCiAgICAgICAgcHJpdmF0ZSBBZHZlcnRpc2VyQWR2ZXJ0aXNlUGFyYW1zKGludCB2ZXJzaW9uKSB7CiAgICAgICAgICAgIHN1cGVyKFNUUlVDVF9TSVpFLCB2ZXJzaW9uKTsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgQWR2ZXJ0aXNlckFkdmVydGlzZVBhcmFtcygpIHsKICAgICAgICAgICAgdGhpcygwKTsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgc3RhdGljIEFkdmVydGlzZXJBZHZlcnRpc2VQYXJhbXMgZGVzZXJpYWxpemUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBkZWNvZGUobmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIobWVzc2FnZSkpOwogICAgICAgIH0KICAgIAogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIHB1YmxpYyBzdGF0aWMgQWR2ZXJ0aXNlckFkdmVydGlzZVBhcmFtcyBkZWNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMCkgewogICAgICAgICAgICBpZiAoZGVjb2RlcjAgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBtYWluRGF0YUhlYWRlciA9IGRlY29kZXIwLnJlYWRBbmRWYWxpZGF0ZURhdGFIZWFkZXIoVkVSU0lPTl9BUlJBWSk7CiAgICAgICAgICAgIEFkdmVydGlzZXJBZHZlcnRpc2VQYXJhbXMgcmVzdWx0ID0gbmV3IEFkdmVydGlzZXJBZHZlcnRpc2VQYXJhbXMobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24pOwogICAgICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMSA9IGRlY29kZXIwLnJlYWRQb2ludGVyKDgsIGZhbHNlKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5zZXJ2aWNlID0gU2VydmljZS5kZWNvZGUoZGVjb2RlcjEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbiA+PSAwKSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyIGRlY29kZXIxID0gZGVjb2RlcjAucmVhZFBvaW50ZXIoMTYsIHRydWUpOwogICAgICAgICAgICAgICAgaWYgKGRlY29kZXIxID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQudmlzaWJpbGl0eSA9IG51bGw7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgc2kxID0gZGVjb2RlcjEucmVhZERhdGFIZWFkZXJGb3JQb2ludGVyQXJyYXkob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuVU5TUEVDSUZJRURfQVJSQVlfTEVOR1RIKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQudmlzaWJpbGl0eSA9IG5ldyBTdHJpbmdbc2kxLmVsZW1lbnRzT3JWZXJzaW9uXTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpMSA9IDA7IGkxIDwgc2kxLmVsZW1lbnRzT3JWZXJzaW9uOyArK2kxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC52aXNpYmlsaXR5W2kxXSA9IGRlY29kZXIxLnJlYWRTdHJpbmcob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlci5IRUFERVJfU0laRSArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLlBPSU5URVJfU0laRSAqIGkxLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgZW5jb2RlKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcikgewogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIwID0gZW5jb2Rlci5nZXRFbmNvZGVyQXREYXRhT2Zmc2V0KERFRkFVTFRfU1RSVUNUX0lORk8pOwogICAgICAgICAgICBlbmNvZGVyMC5lbmNvZGUoc2VydmljZSwgOCwgZmFsc2UpOwogICAgICAgICAgICBpZiAodmlzaWJpbGl0eSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBlbmNvZGVyMC5lbmNvZGVOdWxsUG9pbnRlcigxNiwgdHJ1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIxID0gZW5jb2RlcjAuZW5jb2RlUG9pbnRlckFycmF5KHZpc2liaWxpdHkubGVuZ3RoLCAxNiwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuVU5TUEVDSUZJRURfQVJSQVlfTEVOR1RIKTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkwID0gMDsgaTAgPCB2aXNpYmlsaXR5Lmxlbmd0aDsgKytpMCkgewogICAgICAgICAgICAgICAgICAgIGVuY29kZXIxLmVuY29kZSh2aXNpYmlsaXR5W2kwXSwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlci5IRUFERVJfU0laRSArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLlBPSU5URVJfU0laRSAqIGkwLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIE9iamVjdCNlcXVhbHMoT2JqZWN0KQogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CiAgICAgICAgICAgIGlmIChvYmplY3QgPT0gdGhpcykKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmIChnZXRDbGFzcygpICE9IG9iamVjdC5nZXRDbGFzcygpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBBZHZlcnRpc2VyQWR2ZXJ0aXNlUGFyYW1zIG90aGVyID0gKEFkdmVydGlzZXJBZHZlcnRpc2VQYXJhbXMpIG9iamVjdDsKICAgICAgICAgICAgaWYgKCFvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5lcXVhbHModGhpcy5zZXJ2aWNlLCBvdGhlci5zZXJ2aWNlKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgaWYgKCFqYXZhLnV0aWwuQXJyYXlzLmRlZXBFcXVhbHModGhpcy52aXNpYmlsaXR5LCBvdGhlci52aXNpYmlsaXR5KSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBPYmplY3QjaGFzaENvZGUoKQogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICAgIGZpbmFsIGludCBwcmltZSA9IDMxOwogICAgICAgICAgICBpbnQgcmVzdWx0ID0gcHJpbWUgKyBnZXRDbGFzcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuaGFzaENvZGUoc2VydmljZSk7CiAgICAgICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgamF2YS51dGlsLkFycmF5cy5kZWVwSGFzaENvZGUodmlzaWJpbGl0eSk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBBZHZlcnRpc2VyQWR2ZXJ0aXNlUmVzcG9uc2VQYXJhbXMgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TdHJ1Y3QgewogICAgCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNUUlVDVF9TSVpFID0gMzI7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIFZFUlNJT05fQVJSQVkgPSBuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIHtuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcigzMiwgMCl9OwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgREVGQVVMVF9TVFJVQ1RfSU5GTyA9IFZFUlNJT05fQVJSQVlbMF07CiAgICAKICAgICAgICBwdWJsaWMgaW50IGhhbmRsZTsKICAgICAgICBwdWJsaWMgU3RyaW5nIGluc3RhbmNlSWQ7CiAgICAgICAgcHVibGljIEVycm9yIGVycjsKICAgIAogICAgICAgIHByaXZhdGUgQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zKGludCB2ZXJzaW9uKSB7CiAgICAgICAgICAgIHN1cGVyKFNUUlVDVF9TSVpFLCB2ZXJzaW9uKTsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zKCkgewogICAgICAgICAgICB0aGlzKDApOwogICAgICAgIH0KICAgIAogICAgICAgIHB1YmxpYyBzdGF0aWMgQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zIGRlc2VyaWFsaXplKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2UgbWVzc2FnZSkgewogICAgICAgICAgICByZXR1cm4gZGVjb2RlKG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyKG1lc3NhZ2UpKTsKICAgICAgICB9CiAgICAKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBwdWJsaWMgc3RhdGljIEFkdmVydGlzZXJBZHZlcnRpc2VSZXNwb25zZVBhcmFtcyBkZWNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMCkgewogICAgICAgICAgICBpZiAoZGVjb2RlcjAgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBtYWluRGF0YUhlYWRlciA9IGRlY29kZXIwLnJlYWRBbmRWYWxpZGF0ZURhdGFIZWFkZXIoVkVSU0lPTl9BUlJBWSk7CiAgICAgICAgICAgIEFkdmVydGlzZXJBZHZlcnRpc2VSZXNwb25zZVBhcmFtcyByZXN1bHQgPSBuZXcgQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uKTsKICAgICAgICAgICAgaWYgKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uID49IDApIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5oYW5kbGUgPSBkZWNvZGVyMC5yZWFkSW50KDgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbiA+PSAwKSB7CiAgICAgICAgICAgICAgICByZXN1bHQuaW5zdGFuY2VJZCA9IGRlY29kZXIwLnJlYWRTdHJpbmcoMTYsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMSA9IGRlY29kZXIwLnJlYWRQb2ludGVyKDI0LCB0cnVlKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5lcnIgPSBFcnJvci5kZWNvZGUoZGVjb2RlcjEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgZW5jb2RlKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcikgewogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIwID0gZW5jb2Rlci5nZXRFbmNvZGVyQXREYXRhT2Zmc2V0KERFRkFVTFRfU1RSVUNUX0lORk8pOwogICAgICAgICAgICBlbmNvZGVyMC5lbmNvZGUoaGFuZGxlLCA4KTsKICAgICAgICAgICAgZW5jb2RlcjAuZW5jb2RlKGluc3RhbmNlSWQsIDE2LCBmYWxzZSk7CiAgICAgICAgICAgIGVuY29kZXIwLmVuY29kZShlcnIsIDI0LCB0cnVlKTsKICAgICAgICB9CiAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIE9iamVjdCNlcXVhbHMoT2JqZWN0KQogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CiAgICAgICAgICAgIGlmIChvYmplY3QgPT0gdGhpcykKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmIChnZXRDbGFzcygpICE9IG9iamVjdC5nZXRDbGFzcygpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBBZHZlcnRpc2VyQWR2ZXJ0aXNlUmVzcG9uc2VQYXJhbXMgb3RoZXIgPSAoQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zKSBvYmplY3Q7CiAgICAgICAgICAgIGlmICh0aGlzLmhhbmRsZSAhPSBvdGhlci5oYW5kbGUpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmICghb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuZXF1YWxzKHRoaXMuaW5zdGFuY2VJZCwgb3RoZXIuaW5zdGFuY2VJZCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmICghb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuZXF1YWxzKHRoaXMuZXJyLCBvdGhlci5lcnIpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIE9iamVjdCNoYXNoQ29kZSgpCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgZmluYWwgaW50IHByaW1lID0gMzE7CiAgICAgICAgICAgIGludCByZXN1bHQgPSBwcmltZSArIGdldENsYXNzKCkuaGFzaENvZGUoKTsKICAgICAgICAgICAgcmVzdWx0ID0gcHJpbWUgKiByZXN1bHQgKyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5oYXNoQ29kZShoYW5kbGUpOwogICAgICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGluc3RhbmNlSWQpOwogICAgICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGVycik7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBBZHZlcnRpc2VyQWR2ZXJ0aXNlUmVzcG9uc2VQYXJhbXNGb3J3YXJkVG9DYWxsYmFjayBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlNpZGVFZmZlY3RGcmVlQ2xvc2VhYmxlCiAgICAgICAgICAgIGltcGxlbWVudHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZVJlY2VpdmVyIHsKICAgICAgICBwcml2YXRlIGZpbmFsIEFkdmVydGlzZXIuQWR2ZXJ0aXNlUmVzcG9uc2UgbUNhbGxiYWNrOwoKICAgICAgICBBZHZlcnRpc2VyQWR2ZXJ0aXNlUmVzcG9uc2VQYXJhbXNGb3J3YXJkVG9DYWxsYmFjayhBZHZlcnRpc2VyLkFkdmVydGlzZVJlc3BvbnNlIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIHRoaXMubUNhbGxiYWNrID0gY2FsbGJhY2s7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHQob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TZXJ2aWNlTWVzc2FnZSBtZXNzYWdlV2l0aEhlYWRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXNTZXJ2aWNlTWVzc2FnZSgpOwogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlciBoZWFkZXIgPSBtZXNzYWdlV2l0aEhlYWRlci5nZXRIZWFkZXIoKTsKICAgICAgICAgICAgICAgIGlmICghaGVhZGVyLnZhbGlkYXRlSGVhZGVyKEFEVkVSVElTRV9PUkRJTkFMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlci5NRVNTQUdFX0lTX1JFU1BPTlNFX0ZMQUcpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zIHJlc3BvbnNlID0gQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zLmRlc2VyaWFsaXplKG1lc3NhZ2VXaXRoSGVhZGVyLmdldFBheWxvYWQoKSk7CiAgICAgICAgICAgICAgICBtQ2FsbGJhY2suY2FsbChyZXNwb25zZS5oYW5kbGUsIHJlc3BvbnNlLmluc3RhbmNlSWQsIHJlc3BvbnNlLmVycik7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBjYXRjaCAob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVzZXJpYWxpemF0aW9uRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zUHJveHlUb1Jlc3BvbmRlciBpbXBsZW1lbnRzIEFkdmVydGlzZXIuQWR2ZXJ0aXNlUmVzcG9uc2UgewoKICAgICAgICBwcml2YXRlIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLnN5c3RlbS5Db3JlIG1Db3JlOwogICAgICAgIHByaXZhdGUgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZVJlY2VpdmVyIG1NZXNzYWdlUmVjZWl2ZXI7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nIG1SZXF1ZXN0SWQ7CgogICAgICAgIEFkdmVydGlzZXJBZHZlcnRpc2VSZXNwb25zZVBhcmFtc1Byb3h5VG9SZXNwb25kZXIoCiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5zeXN0ZW0uQ29yZSBjb3JlLAogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZVJlY2VpdmVyIG1lc3NhZ2VSZWNlaXZlciwKICAgICAgICAgICAgICAgIGxvbmcgcmVxdWVzdElkKSB7CiAgICAgICAgICAgIG1Db3JlID0gY29yZTsKICAgICAgICAgICAgbU1lc3NhZ2VSZWNlaXZlciA9IG1lc3NhZ2VSZWNlaXZlcjsKICAgICAgICAgICAgbVJlcXVlc3RJZCA9IHJlcXVlc3RJZDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGNhbGwoSW50ZWdlciBoYW5kbGUsIFN0cmluZyBpbnN0YW5jZUlkLCBFcnJvciBlcnIpIHsKICAgICAgICAgICAgQWR2ZXJ0aXNlckFkdmVydGlzZVJlc3BvbnNlUGFyYW1zIF9yZXNwb25zZSA9IG5ldyBBZHZlcnRpc2VyQWR2ZXJ0aXNlUmVzcG9uc2VQYXJhbXMoKTsKICAgICAgICAgICAgX3Jlc3BvbnNlLmhhbmRsZSA9IGhhbmRsZTsKICAgICAgICAgICAgX3Jlc3BvbnNlLmluc3RhbmNlSWQgPSBpbnN0YW5jZUlkOwogICAgICAgICAgICBfcmVzcG9uc2UuZXJyID0gZXJyOwogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TZXJ2aWNlTWVzc2FnZSBfbWVzc2FnZSA9CiAgICAgICAgICAgICAgICAgICAgX3Jlc3BvbnNlLnNlcmlhbGl6ZVdpdGhIZWFkZXIoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtQ29yZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBRFZFUlRJU0VfT1JESU5BTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlci5NRVNTQUdFX0lTX1JFU1BPTlNFX0ZMQUcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1SZXF1ZXN0SWQpKTsKICAgICAgICAgICAgbU1lc3NhZ2VSZWNlaXZlci5hY2NlcHQoX21lc3NhZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgZmluYWwgY2xhc3MgQWR2ZXJ0aXNlclN0b3BQYXJhbXMgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TdHJ1Y3QgewogICAgCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNUUlVDVF9TSVpFID0gMTY7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIFZFUlNJT05fQVJSQVkgPSBuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIHtuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcigxNiwgMCl9OwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgREVGQVVMVF9TVFJVQ1RfSU5GTyA9IFZFUlNJT05fQVJSQVlbMF07CiAgICAKICAgICAgICBwdWJsaWMgaW50IGg7CiAgICAKICAgICAgICBwcml2YXRlIEFkdmVydGlzZXJTdG9wUGFyYW1zKGludCB2ZXJzaW9uKSB7CiAgICAgICAgICAgIHN1cGVyKFNUUlVDVF9TSVpFLCB2ZXJzaW9uKTsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgQWR2ZXJ0aXNlclN0b3BQYXJhbXMoKSB7CiAgICAgICAgICAgIHRoaXMoMCk7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIHN0YXRpYyBBZHZlcnRpc2VyU3RvcFBhcmFtcyBkZXNlcmlhbGl6ZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlIG1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIGRlY29kZShuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlcihtZXNzYWdlKSk7CiAgICAgICAgfQogICAgCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgcHVibGljIHN0YXRpYyBBZHZlcnRpc2VyU3RvcFBhcmFtcyBkZWNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMCkgewogICAgICAgICAgICBpZiAoZGVjb2RlcjAgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBtYWluRGF0YUhlYWRlciA9IGRlY29kZXIwLnJlYWRBbmRWYWxpZGF0ZURhdGFIZWFkZXIoVkVSU0lPTl9BUlJBWSk7CiAgICAgICAgICAgIEFkdmVydGlzZXJTdG9wUGFyYW1zIHJlc3VsdCA9IG5ldyBBZHZlcnRpc2VyU3RvcFBhcmFtcyhtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbik7CiAgICAgICAgICAgIGlmIChtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbiA+PSAwKSB7CiAgICAgICAgICAgICAgICByZXN1bHQuaCA9IGRlY29kZXIwLnJlYWRJbnQoOCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyKSB7CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcjAgPSBlbmNvZGVyLmdldEVuY29kZXJBdERhdGFPZmZzZXQoREVGQVVMVF9TVFJVQ1RfSU5GTyk7CiAgICAgICAgICAgIGVuY29kZXIwLmVuY29kZShoLCA4KTsKICAgICAgICB9CiAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIE9iamVjdCNlcXVhbHMoT2JqZWN0KQogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CiAgICAgICAgICAgIGlmIChvYmplY3QgPT0gdGhpcykKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmIChnZXRDbGFzcygpICE9IG9iamVjdC5nZXRDbGFzcygpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBBZHZlcnRpc2VyU3RvcFBhcmFtcyBvdGhlciA9IChBZHZlcnRpc2VyU3RvcFBhcmFtcykgb2JqZWN0OwogICAgICAgICAgICBpZiAodGhpcy5oICE9IG90aGVyLmgpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIAogICAgICAgIC8qKgogICAgICAgICAqIEBzZWUgT2JqZWN0I2hhc2hDb2RlKCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICBmaW5hbCBpbnQgcHJpbWUgPSAzMTsKICAgICAgICAgICAgaW50IHJlc3VsdCA9IHByaW1lICsgZ2V0Q2xhc3MoKS5oYXNoQ29kZSgpOwogICAgICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGgpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgZmluYWwgY2xhc3MgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtcyBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlN0cnVjdCB7CiAgICAKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU1RSVUNUX1NJWkUgPSAxNjsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyW10gVkVSU0lPTl9BUlJBWSA9IG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyW10ge25ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyKDE2LCAwKX07CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBERUZBVUxUX1NUUlVDVF9JTkZPID0gVkVSU0lPTl9BUlJBWVswXTsKICAgIAogICAgICAgIHB1YmxpYyBFcnJvciBlcnI7CiAgICAKICAgICAgICBwcml2YXRlIEFkdmVydGlzZXJTdG9wUmVzcG9uc2VQYXJhbXMoaW50IHZlcnNpb24pIHsKICAgICAgICAgICAgc3VwZXIoU1RSVUNUX1NJWkUsIHZlcnNpb24pOwogICAgICAgIH0KICAgIAogICAgICAgIHB1YmxpYyBBZHZlcnRpc2VyU3RvcFJlc3BvbnNlUGFyYW1zKCkgewogICAgICAgICAgICB0aGlzKDApOwogICAgICAgIH0KICAgIAogICAgICAgIHB1YmxpYyBzdGF0aWMgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtcyBkZXNlcmlhbGl6ZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlIG1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIGRlY29kZShuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlcihtZXNzYWdlKSk7CiAgICAgICAgfQogICAgCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgcHVibGljIHN0YXRpYyBBZHZlcnRpc2VyU3RvcFJlc3BvbnNlUGFyYW1zIGRlY29kZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyIGRlY29kZXIwKSB7CiAgICAgICAgICAgIGlmIChkZWNvZGVyMCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyIG1haW5EYXRhSGVhZGVyID0gZGVjb2RlcjAucmVhZEFuZFZhbGlkYXRlRGF0YUhlYWRlcihWRVJTSU9OX0FSUkFZKTsKICAgICAgICAgICAgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtcyByZXN1bHQgPSBuZXcgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtcyhtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbik7CiAgICAgICAgICAgIGlmIChtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbiA+PSAwKSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyIGRlY29kZXIxID0gZGVjb2RlcjAucmVhZFBvaW50ZXIoOCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICByZXN1bHQuZXJyID0gRXJyb3IuZGVjb2RlKGRlY29kZXIxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgIAogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIEBPdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBmaW5hbCB2b2lkIGVuY29kZShvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIpIHsKICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyMCA9IGVuY29kZXIuZ2V0RW5jb2RlckF0RGF0YU9mZnNldChERUZBVUxUX1NUUlVDVF9JTkZPKTsKICAgICAgICAgICAgZW5jb2RlcjAuZW5jb2RlKGVyciwgOCwgdHJ1ZSk7CiAgICAgICAgfQogICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBPYmplY3QjZXF1YWxzKE9iamVjdCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgewogICAgICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmplY3QuZ2V0Q2xhc3MoKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtcyBvdGhlciA9IChBZHZlcnRpc2VyU3RvcFJlc3BvbnNlUGFyYW1zKSBvYmplY3Q7CiAgICAgICAgICAgIGlmICghb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuZXF1YWxzKHRoaXMuZXJyLCBvdGhlci5lcnIpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIE9iamVjdCNoYXNoQ29kZSgpCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgZmluYWwgaW50IHByaW1lID0gMzE7CiAgICAgICAgICAgIGludCByZXN1bHQgPSBwcmltZSArIGdldENsYXNzKCkuaGFzaENvZGUoKTsKICAgICAgICAgICAgcmVzdWx0ID0gcHJpbWUgKiByZXN1bHQgKyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5oYXNoQ29kZShlcnIpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtc0ZvcndhcmRUb0NhbGxiYWNrIGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuU2lkZUVmZmVjdEZyZWVDbG9zZWFibGUKICAgICAgICAgICAgaW1wbGVtZW50cyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlUmVjZWl2ZXIgewogICAgICAgIHByaXZhdGUgZmluYWwgQWR2ZXJ0aXNlci5TdG9wUmVzcG9uc2UgbUNhbGxiYWNrOwoKICAgICAgICBBZHZlcnRpc2VyU3RvcFJlc3BvbnNlUGFyYW1zRm9yd2FyZFRvQ2FsbGJhY2soQWR2ZXJ0aXNlci5TdG9wUmVzcG9uc2UgY2FsbGJhY2spIHsKICAgICAgICAgICAgdGhpcy5tQ2FsbGJhY2sgPSBjYWxsYmFjazsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdChvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlIG1lc3NhZ2UpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlNlcnZpY2VNZXNzYWdlIG1lc3NhZ2VXaXRoSGVhZGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hc1NlcnZpY2VNZXNzYWdlKCk7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyIGhlYWRlciA9IG1lc3NhZ2VXaXRoSGVhZGVyLmdldEhlYWRlcigpOwogICAgICAgICAgICAgICAgaWYgKCFoZWFkZXIudmFsaWRhdGVIZWFkZXIoU1RPUF9PUkRJTkFMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlci5NRVNTQUdFX0lTX1JFU1BPTlNFX0ZMQUcpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtcyByZXNwb25zZSA9IEFkdmVydGlzZXJTdG9wUmVzcG9uc2VQYXJhbXMuZGVzZXJpYWxpemUobWVzc2FnZVdpdGhIZWFkZXIuZ2V0UGF5bG9hZCgpKTsKICAgICAgICAgICAgICAgIG1DYWxsYmFjay5jYWxsKHJlc3BvbnNlLmVycik7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBjYXRjaCAob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVzZXJpYWxpemF0aW9uRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtc1Byb3h5VG9SZXNwb25kZXIgaW1wbGVtZW50cyBBZHZlcnRpc2VyLlN0b3BSZXNwb25zZSB7CgogICAgICAgIHByaXZhdGUgZmluYWwgb3JnLmNocm9taXVtLm1vam8uc3lzdGVtLkNvcmUgbUNvcmU7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlUmVjZWl2ZXIgbU1lc3NhZ2VSZWNlaXZlcjsKICAgICAgICBwcml2YXRlIGZpbmFsIGxvbmcgbVJlcXVlc3RJZDsKCiAgICAgICAgQWR2ZXJ0aXNlclN0b3BSZXNwb25zZVBhcmFtc1Byb3h5VG9SZXNwb25kZXIoCiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5zeXN0ZW0uQ29yZSBjb3JlLAogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZVJlY2VpdmVyIG1lc3NhZ2VSZWNlaXZlciwKICAgICAgICAgICAgICAgIGxvbmcgcmVxdWVzdElkKSB7CiAgICAgICAgICAgIG1Db3JlID0gY29yZTsKICAgICAgICAgICAgbU1lc3NhZ2VSZWNlaXZlciA9IG1lc3NhZ2VSZWNlaXZlcjsKICAgICAgICAgICAgbVJlcXVlc3RJZCA9IHJlcXVlc3RJZDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIGNhbGwoRXJyb3IgZXJyKSB7CiAgICAgICAgICAgIEFkdmVydGlzZXJTdG9wUmVzcG9uc2VQYXJhbXMgX3Jlc3BvbnNlID0gbmV3IEFkdmVydGlzZXJTdG9wUmVzcG9uc2VQYXJhbXMoKTsKICAgICAgICAgICAgX3Jlc3BvbnNlLmVyciA9IGVycjsKICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuU2VydmljZU1lc3NhZ2UgX21lc3NhZ2UgPQogICAgICAgICAgICAgICAgICAgIF9yZXNwb25zZS5zZXJpYWxpemVXaXRoSGVhZGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbUNvcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RPUF9PUkRJTkFMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyLk1FU1NBR0VfSVNfUkVTUE9OU0VfRkxBRywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbVJlcXVlc3RJZCkpOwogICAgICAgICAgICBtTWVzc2FnZVJlY2VpdmVyLmFjY2VwdChfbWVzc2FnZSk7CiAgICAgICAgfQogICAgfQoKfQoKUEsDBBQAAAAAAFl2J0hBzGQFswMAALMDAAAjAAAAaW8vdi9tb2pvL2Rpc2NvdmVyeS9BZHZlcnRpc2VyLmphdmEvLyBDb3B5cmlnaHQgMjAxNCBUaGUgQ2hyb21pdW0gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KLy8gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZQovLyBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKLy8gVGhpcyBmaWxlIGlzIGF1dG9nZW5lcmF0ZWQgYnk6Ci8vICAgICBtb2pvL3B1YmxpYy90b29scy9iaW5kaW5ncy9tb2pvbV9iaW5kaW5nc19nZW5lcmF0b3IucHkKLy8gRm9yOgovLyAgICAgbW9qb20vdmFuYWRpdW0vZGlzY292ZXJ5Lm1vam9tCi8vCgpwYWNrYWdlIGlvLnYubW9qby5kaXNjb3Zlcnk7CgpwdWJsaWMgaW50ZXJmYWNlIEFkdmVydGlzZXIgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2UgewoKICAgIHB1YmxpYyBpbnRlcmZhY2UgUHJveHkgZXh0ZW5kcyBBZHZlcnRpc2VyLCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2UuUHJveHkgewogICAgfQoKICAgIE5hbWVkTWFuYWdlcjxBZHZlcnRpc2VyLCBBZHZlcnRpc2VyLlByb3h5PiBNQU5BR0VSID0gQWR2ZXJ0aXNlcl9JbnRlcm5hbC5NQU5BR0VSOwoKICAgIHZvaWQgYWR2ZXJ0aXNlKFNlcnZpY2Ugc2VydmljZSwgU3RyaW5nW10gdmlzaWJpbGl0eSwgQWR2ZXJ0aXNlUmVzcG9uc2UgY2FsbGJhY2spOwogICAgaW50ZXJmYWNlIEFkdmVydGlzZVJlc3BvbnNlIGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQ2FsbGJhY2tzLkNhbGxiYWNrMzxJbnRlZ2VyLCBTdHJpbmcsIEVycm9yPiB7IH0KCiAgICB2b2lkIHN0b3AoaW50IGgsIFN0b3BSZXNwb25zZSBjYWxsYmFjayk7CiAgICBpbnRlcmZhY2UgU3RvcFJlc3BvbnNlIGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQ2FsbGJhY2tzLkNhbGxiYWNrMTxFcnJvcj4geyB9Cn0KClBLAwQUAAAAAABZdidI9ltbu9NaAADTWgAAKQAAAGlvL3YvbW9qby9kaXNjb3ZlcnkvU2Nhbm5lcl9JbnRlcm5hbC5qYXZhLy8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIFRoaXMgZmlsZSBpcyBhdXRvZ2VuZXJhdGVkIGJ5OgovLyAgICAgbW9qby9wdWJsaWMvdG9vbHMvYmluZGluZ3MvbW9qb21fYmluZGluZ3NfZ2VuZXJhdG9yLnB5Ci8vIEZvcjoKLy8gICAgIG1vam9tL3ZhbmFkaXVtL2Rpc2NvdmVyeS5tb2pvbQovLwoKcGFja2FnZSBpby52Lm1vam8uZGlzY292ZXJ5OwoKY2xhc3MgU2Nhbm5lcl9JbnRlcm5hbCB7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2UuTmFtZWRNYW5hZ2VyPFNjYW5uZXIsIFNjYW5uZXIuUHJveHk+IE1BTkFHRVIgPQogICAgICAgICAgICBuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlLk5hbWVkTWFuYWdlcjxTY2FubmVyLCBTY2FubmVyLlByb3h5PigpIHsKICAgIAogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuICJ2MjM6OmRpc2NvdmVyeTo6U2Nhbm5lciI7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIGludCBnZXRWZXJzaW9uKCkgewogICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFByb3h5IGJ1aWxkUHJveHkob3JnLmNocm9taXVtLm1vam8uc3lzdGVtLkNvcmUgY29yZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlUmVjZWl2ZXJXaXRoUmVzcG9uZGVyIG1lc3NhZ2VSZWNlaXZlcikgewogICAgICAgICAgICByZXR1cm4gbmV3IFByb3h5KGNvcmUsIG1lc3NhZ2VSZWNlaXZlcik7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFN0dWIgYnVpbGRTdHViKG9yZy5jaHJvbWl1bS5tb2pvLnN5c3RlbS5Db3JlIGNvcmUsIFNjYW5uZXIgaW1wbCkgewogICAgICAgICAgICByZXR1cm4gbmV3IFN0dWIoY29yZSwgaW1wbCk7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFNjYW5uZXJbXSBidWlsZEFycmF5KGludCBzaXplKSB7CiAgICAgICAgICByZXR1cm4gbmV3IFNjYW5uZXJbc2l6ZV07CiAgICAgICAgfQogICAgfTsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0NBTl9PUkRJTkFMID0gMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVE9QX09SRElOQUwgPSAxOwoKICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm94eSBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkludGVyZmFjZS5BYnN0cmFjdFByb3h5IGltcGxlbWVudHMgU2Nhbm5lci5Qcm94eSB7CgogICAgICAgIFByb3h5KG9yZy5jaHJvbWl1bS5tb2pvLnN5c3RlbS5Db3JlIGNvcmUsCiAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZVJlY2VpdmVyV2l0aFJlc3BvbmRlciBtZXNzYWdlUmVjZWl2ZXIpIHsKICAgICAgICAgICAgc3VwZXIoY29yZSwgbWVzc2FnZVJlY2VpdmVyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHNjYW4oU3RyaW5nIHF1ZXJ5LCBTY2FuSGFuZGxlciBzY2FuSGFuZGxlciwgU2NhblJlc3BvbnNlIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIFNjYW5uZXJTY2FuUGFyYW1zIF9tZXNzYWdlID0gbmV3IFNjYW5uZXJTY2FuUGFyYW1zKCk7CiAgICAgICAgICAgIF9tZXNzYWdlLnF1ZXJ5ID0gcXVlcnk7CiAgICAgICAgICAgIF9tZXNzYWdlLnNjYW5IYW5kbGVyID0gc2NhbkhhbmRsZXI7CiAgICAgICAgICAgIGdldFByb3h5SGFuZGxlcigpLmdldE1lc3NhZ2VSZWNlaXZlcigpLmFjY2VwdFdpdGhSZXNwb25kZXIoCiAgICAgICAgICAgICAgICAgICAgX21lc3NhZ2Uuc2VyaWFsaXplV2l0aEhlYWRlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByb3h5SGFuZGxlcigpLmdldENvcmUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX09SRElOQUwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIuTUVTU0FHRV9FWFBFQ1RTX1JFU1BPTlNFX0ZMQUcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApKSwKICAgICAgICAgICAgICAgICAgICBuZXcgU2Nhbm5lclNjYW5SZXNwb25zZVBhcmFtc0ZvcndhcmRUb0NhbGxiYWNrKGNhbGxiYWNrKSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBzdG9wKGludCBoLCBTdG9wUmVzcG9uc2UgY2FsbGJhY2spIHsKICAgICAgICAgICAgU2Nhbm5lclN0b3BQYXJhbXMgX21lc3NhZ2UgPSBuZXcgU2Nhbm5lclN0b3BQYXJhbXMoKTsKICAgICAgICAgICAgX21lc3NhZ2UuaCA9IGg7CiAgICAgICAgICAgIGdldFByb3h5SGFuZGxlcigpLmdldE1lc3NhZ2VSZWNlaXZlcigpLmFjY2VwdFdpdGhSZXNwb25kZXIoCiAgICAgICAgICAgICAgICAgICAgX21lc3NhZ2Uuc2VyaWFsaXplV2l0aEhlYWRlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByb3h5SGFuZGxlcigpLmdldENvcmUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVE9QX09SRElOQUwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIuTUVTU0FHRV9FWFBFQ1RTX1JFU1BPTlNFX0ZMQUcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApKSwKICAgICAgICAgICAgICAgICAgICBuZXcgU2Nhbm5lclN0b3BSZXNwb25zZVBhcmFtc0ZvcndhcmRUb0NhbGxiYWNrKGNhbGxiYWNrKSk7CiAgICAgICAgfQoKICAgIH0KCiAgICBzdGF0aWMgZmluYWwgY2xhc3MgU3R1YiBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkludGVyZmFjZS5TdHViPFNjYW5uZXI+IHsKCiAgICAgICAgU3R1YihvcmcuY2hyb21pdW0ubW9qby5zeXN0ZW0uQ29yZSBjb3JlLCBTY2FubmVyIGltcGwpIHsKICAgICAgICAgICAgc3VwZXIoY29yZSwgaW1wbCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHQob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TZXJ2aWNlTWVzc2FnZSBtZXNzYWdlV2l0aEhlYWRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXNTZXJ2aWNlTWVzc2FnZSgpOwogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlciBoZWFkZXIgPSBtZXNzYWdlV2l0aEhlYWRlci5nZXRIZWFkZXIoKTsKICAgICAgICAgICAgICAgIGlmICghaGVhZGVyLnZhbGlkYXRlSGVhZGVyKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIuTk9fRkxBRykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzd2l0Y2goaGVhZGVyLmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2Ugb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlQ29udHJvbE1lc3NhZ2VzQ29uc3RhbnRzLlJVTl9PUl9DTE9TRV9QSVBFX01FU1NBR0VfSUQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5JbnRlcmZhY2VDb250cm9sTWVzc2FnZXNIZWxwZXIuaGFuZGxlUnVuT3JDbG9zZVBpcGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2Nhbm5lcl9JbnRlcm5hbC5NQU5BR0VSLCBtZXNzYWdlV2l0aEhlYWRlcik7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZXNlcmlhbGl6YXRpb25FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgU3lzdGVtLmVyci5wcmludGxuKGUudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGFjY2VwdFdpdGhSZXNwb25kZXIob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlLCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlUmVjZWl2ZXIgcmVjZWl2ZXIpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlNlcnZpY2VNZXNzYWdlIG1lc3NhZ2VXaXRoSGVhZGVyID0KICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hc1NlcnZpY2VNZXNzYWdlKCk7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyIGhlYWRlciA9IG1lc3NhZ2VXaXRoSGVhZGVyLmdldEhlYWRlcigpOwogICAgICAgICAgICAgICAgaWYgKCFoZWFkZXIudmFsaWRhdGVIZWFkZXIob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlci5NRVNTQUdFX0VYUEVDVFNfUkVTUE9OU0VfRkxBRykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzd2l0Y2goaGVhZGVyLmdldFR5cGUoKSkgewogICAgICAgICAgICAgICAgICAgIGNhc2Ugb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlQ29udHJvbE1lc3NhZ2VzQ29uc3RhbnRzLlJVTl9NRVNTQUdFX0lEOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlQ29udHJvbE1lc3NhZ2VzSGVscGVyLmhhbmRsZVJ1bigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRDb3JlKCksIFNjYW5uZXJfSW50ZXJuYWwuTUFOQUdFUiwgbWVzc2FnZVdpdGhIZWFkZXIsIHJlY2VpdmVyKTsKICAgICAgICAgICAgICAgICAgICBjYXNlIFNDQU5fT1JESU5BTDogewogICAgICAgICAgICAgICAgICAgICAgICBTY2FubmVyU2NhblBhcmFtcyBkYXRhID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTY2FubmVyU2NhblBhcmFtcy5kZXNlcmlhbGl6ZShtZXNzYWdlV2l0aEhlYWRlci5nZXRQYXlsb2FkKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBnZXRJbXBsKCkuc2NhbihkYXRhLnF1ZXJ5LCBkYXRhLnNjYW5IYW5kbGVyLCBuZXcgU2Nhbm5lclNjYW5SZXNwb25zZVBhcmFtc1Byb3h5VG9SZXNwb25kZXIoZ2V0Q29yZSgpLCByZWNlaXZlciwgaGVhZGVyLmdldFJlcXVlc3RJZCgpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXNlIFNUT1BfT1JESU5BTDogewogICAgICAgICAgICAgICAgICAgICAgICBTY2FubmVyU3RvcFBhcmFtcyBkYXRhID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTY2FubmVyU3RvcFBhcmFtcy5kZXNlcmlhbGl6ZShtZXNzYWdlV2l0aEhlYWRlci5nZXRQYXlsb2FkKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBnZXRJbXBsKCkuc3RvcChkYXRhLmgsIG5ldyBTY2FubmVyU3RvcFJlc3BvbnNlUGFyYW1zUHJveHlUb1Jlc3BvbmRlcihnZXRDb3JlKCksIHJlY2VpdmVyLCBoZWFkZXIuZ2V0UmVxdWVzdElkKCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVzZXJpYWxpemF0aW9uRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgIFN5c3RlbS5lcnIucHJpbnRsbihlLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBTY2FubmVyU2NhblBhcmFtcyBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlN0cnVjdCB7CiAgICAKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU1RSVUNUX1NJWkUgPSAyNDsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyW10gVkVSU0lPTl9BUlJBWSA9IG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyW10ge25ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyKDI0LCAwKX07CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBERUZBVUxUX1NUUlVDVF9JTkZPID0gVkVSU0lPTl9BUlJBWVswXTsKICAgIAogICAgICAgIHB1YmxpYyBTdHJpbmcgcXVlcnk7CiAgICAgICAgcHVibGljIFNjYW5IYW5kbGVyIHNjYW5IYW5kbGVyOwogICAgCiAgICAgICAgcHJpdmF0ZSBTY2FubmVyU2NhblBhcmFtcyhpbnQgdmVyc2lvbikgewogICAgICAgICAgICBzdXBlcihTVFJVQ1RfU0laRSwgdmVyc2lvbik7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFNjYW5uZXJTY2FuUGFyYW1zKCkgewogICAgICAgICAgICB0aGlzKDApOwogICAgICAgIH0KICAgIAogICAgICAgIHB1YmxpYyBzdGF0aWMgU2Nhbm5lclNjYW5QYXJhbXMgZGVzZXJpYWxpemUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBkZWNvZGUobmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIobWVzc2FnZSkpOwogICAgICAgIH0KICAgIAogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIHB1YmxpYyBzdGF0aWMgU2Nhbm5lclNjYW5QYXJhbXMgZGVjb2RlKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIgZGVjb2RlcjApIHsKICAgICAgICAgICAgaWYgKGRlY29kZXIwID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgbWFpbkRhdGFIZWFkZXIgPSBkZWNvZGVyMC5yZWFkQW5kVmFsaWRhdGVEYXRhSGVhZGVyKFZFUlNJT05fQVJSQVkpOwogICAgICAgICAgICBTY2FubmVyU2NhblBhcmFtcyByZXN1bHQgPSBuZXcgU2Nhbm5lclNjYW5QYXJhbXMobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24pOwogICAgICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICAgICAgcmVzdWx0LnF1ZXJ5ID0gZGVjb2RlcjAucmVhZFN0cmluZyg4LCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uID49IDApIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5zY2FuSGFuZGxlciA9IGRlY29kZXIwLnJlYWRTZXJ2aWNlSW50ZXJmYWNlKDE2LCBmYWxzZSwgU2NhbkhhbmRsZXIuTUFOQUdFUik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyKSB7CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcjAgPSBlbmNvZGVyLmdldEVuY29kZXJBdERhdGFPZmZzZXQoREVGQVVMVF9TVFJVQ1RfSU5GTyk7CiAgICAgICAgICAgIGVuY29kZXIwLmVuY29kZShxdWVyeSwgOCwgZmFsc2UpOwogICAgICAgICAgICBlbmNvZGVyMC5lbmNvZGUoc2NhbkhhbmRsZXIsIDE2LCBmYWxzZSwgU2NhbkhhbmRsZXIuTUFOQUdFUik7CiAgICAgICAgfQogICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBPYmplY3QjZXF1YWxzKE9iamVjdCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgewogICAgICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmplY3QuZ2V0Q2xhc3MoKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgU2Nhbm5lclNjYW5QYXJhbXMgb3RoZXIgPSAoU2Nhbm5lclNjYW5QYXJhbXMpIG9iamVjdDsKICAgICAgICAgICAgaWYgKCFvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5lcXVhbHModGhpcy5xdWVyeSwgb3RoZXIucXVlcnkpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBpZiAoIW9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmVxdWFscyh0aGlzLnNjYW5IYW5kbGVyLCBvdGhlci5zY2FuSGFuZGxlcikpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIAogICAgICAgIC8qKgogICAgICAgICAqIEBzZWUgT2JqZWN0I2hhc2hDb2RlKCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgICBmaW5hbCBpbnQgcHJpbWUgPSAzMTsKICAgICAgICAgICAgaW50IHJlc3VsdCA9IHByaW1lICsgZ2V0Q2xhc3MoKS5oYXNoQ29kZSgpOwogICAgICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKHF1ZXJ5KTsKICAgICAgICAgICAgcmVzdWx0ID0gcHJpbWUgKiByZXN1bHQgKyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5oYXNoQ29kZShzY2FuSGFuZGxlcik7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBmaW5hbCBjbGFzcyBTY2FubmVyU2NhblJlc3BvbnNlUGFyYW1zIGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuU3RydWN0IHsKICAgIAogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVFJVQ1RfU0laRSA9IDI0OwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXJbXSBWRVJTSU9OX0FSUkFZID0gbmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXJbXSB7bmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIoMjQsIDApfTsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyIERFRkFVTFRfU1RSVUNUX0lORk8gPSBWRVJTSU9OX0FSUkFZWzBdOwogICAgCiAgICAgICAgcHVibGljIGludCBoYW5kbGU7CiAgICAgICAgcHVibGljIEVycm9yIGVycjsKICAgIAogICAgICAgIHByaXZhdGUgU2Nhbm5lclNjYW5SZXNwb25zZVBhcmFtcyhpbnQgdmVyc2lvbikgewogICAgICAgICAgICBzdXBlcihTVFJVQ1RfU0laRSwgdmVyc2lvbik7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFNjYW5uZXJTY2FuUmVzcG9uc2VQYXJhbXMoKSB7CiAgICAgICAgICAgIHRoaXMoMCk7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIHN0YXRpYyBTY2FubmVyU2NhblJlc3BvbnNlUGFyYW1zIGRlc2VyaWFsaXplKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2UgbWVzc2FnZSkgewogICAgICAgICAgICByZXR1cm4gZGVjb2RlKG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyKG1lc3NhZ2UpKTsKICAgICAgICB9CiAgICAKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBwdWJsaWMgc3RhdGljIFNjYW5uZXJTY2FuUmVzcG9uc2VQYXJhbXMgZGVjb2RlKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIgZGVjb2RlcjApIHsKICAgICAgICAgICAgaWYgKGRlY29kZXIwID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgbWFpbkRhdGFIZWFkZXIgPSBkZWNvZGVyMC5yZWFkQW5kVmFsaWRhdGVEYXRhSGVhZGVyKFZFUlNJT05fQVJSQVkpOwogICAgICAgICAgICBTY2FubmVyU2NhblJlc3BvbnNlUGFyYW1zIHJlc3VsdCA9IG5ldyBTY2FubmVyU2NhblJlc3BvbnNlUGFyYW1zKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uKTsKICAgICAgICAgICAgaWYgKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uID49IDApIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5oYW5kbGUgPSBkZWNvZGVyMC5yZWFkSW50KDgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbiA+PSAwKSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyIGRlY29kZXIxID0gZGVjb2RlcjAucmVhZFBvaW50ZXIoMTYsIHRydWUpOwogICAgICAgICAgICAgICAgcmVzdWx0LmVyciA9IEVycm9yLmRlY29kZShkZWNvZGVyMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyKSB7CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcjAgPSBlbmNvZGVyLmdldEVuY29kZXJBdERhdGFPZmZzZXQoREVGQVVMVF9TVFJVQ1RfSU5GTyk7CiAgICAgICAgICAgIGVuY29kZXIwLmVuY29kZShoYW5kbGUsIDgpOwogICAgICAgICAgICBlbmNvZGVyMC5lbmNvZGUoZXJyLCAxNiwgdHJ1ZSk7CiAgICAgICAgfQogICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBPYmplY3QjZXF1YWxzKE9iamVjdCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgewogICAgICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmplY3QuZ2V0Q2xhc3MoKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgU2Nhbm5lclNjYW5SZXNwb25zZVBhcmFtcyBvdGhlciA9IChTY2FubmVyU2NhblJlc3BvbnNlUGFyYW1zKSBvYmplY3Q7CiAgICAgICAgICAgIGlmICh0aGlzLmhhbmRsZSAhPSBvdGhlci5oYW5kbGUpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmICghb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuZXF1YWxzKHRoaXMuZXJyLCBvdGhlci5lcnIpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIE9iamVjdCNoYXNoQ29kZSgpCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgZmluYWwgaW50IHByaW1lID0gMzE7CiAgICAgICAgICAgIGludCByZXN1bHQgPSBwcmltZSArIGdldENsYXNzKCkuaGFzaENvZGUoKTsKICAgICAgICAgICAgcmVzdWx0ID0gcHJpbWUgKiByZXN1bHQgKyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5oYXNoQ29kZShoYW5kbGUpOwogICAgICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGVycik7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyBjbGFzcyBTY2FubmVyU2NhblJlc3BvbnNlUGFyYW1zRm9yd2FyZFRvQ2FsbGJhY2sgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TaWRlRWZmZWN0RnJlZUNsb3NlYWJsZQogICAgICAgICAgICBpbXBsZW1lbnRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VSZWNlaXZlciB7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBTY2FubmVyLlNjYW5SZXNwb25zZSBtQ2FsbGJhY2s7CgogICAgICAgIFNjYW5uZXJTY2FuUmVzcG9uc2VQYXJhbXNGb3J3YXJkVG9DYWxsYmFjayhTY2FubmVyLlNjYW5SZXNwb25zZSBjYWxsYmFjaykgewogICAgICAgICAgICB0aGlzLm1DYWxsYmFjayA9IGNhbGxiYWNrOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gYWNjZXB0KG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2UgbWVzc2FnZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuU2VydmljZU1lc3NhZ2UgbWVzc2FnZVdpdGhIZWFkZXIgPQogICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmFzU2VydmljZU1lc3NhZ2UoKTsKICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIgaGVhZGVyID0gbWVzc2FnZVdpdGhIZWFkZXIuZ2V0SGVhZGVyKCk7CiAgICAgICAgICAgICAgICBpZiAoIWhlYWRlci52YWxpZGF0ZUhlYWRlcihTQ0FOX09SRElOQUwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyLk1FU1NBR0VfSVNfUkVTUE9OU0VfRkxBRykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBTY2FubmVyU2NhblJlc3BvbnNlUGFyYW1zIHJlc3BvbnNlID0gU2Nhbm5lclNjYW5SZXNwb25zZVBhcmFtcy5kZXNlcmlhbGl6ZShtZXNzYWdlV2l0aEhlYWRlci5nZXRQYXlsb2FkKCkpOwogICAgICAgICAgICAgICAgbUNhbGxiYWNrLmNhbGwocmVzcG9uc2UuaGFuZGxlLCByZXNwb25zZS5lcnIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gY2F0Y2ggKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIFNjYW5uZXJTY2FuUmVzcG9uc2VQYXJhbXNQcm94eVRvUmVzcG9uZGVyIGltcGxlbWVudHMgU2Nhbm5lci5TY2FuUmVzcG9uc2UgewoKICAgICAgICBwcml2YXRlIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLnN5c3RlbS5Db3JlIG1Db3JlOwogICAgICAgIHByaXZhdGUgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZVJlY2VpdmVyIG1NZXNzYWdlUmVjZWl2ZXI7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nIG1SZXF1ZXN0SWQ7CgogICAgICAgIFNjYW5uZXJTY2FuUmVzcG9uc2VQYXJhbXNQcm94eVRvUmVzcG9uZGVyKAogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uc3lzdGVtLkNvcmUgY29yZSwKICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VSZWNlaXZlciBtZXNzYWdlUmVjZWl2ZXIsCiAgICAgICAgICAgICAgICBsb25nIHJlcXVlc3RJZCkgewogICAgICAgICAgICBtQ29yZSA9IGNvcmU7CiAgICAgICAgICAgIG1NZXNzYWdlUmVjZWl2ZXIgPSBtZXNzYWdlUmVjZWl2ZXI7CiAgICAgICAgICAgIG1SZXF1ZXN0SWQgPSByZXF1ZXN0SWQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBjYWxsKEludGVnZXIgaGFuZGxlLCBFcnJvciBlcnIpIHsKICAgICAgICAgICAgU2Nhbm5lclNjYW5SZXNwb25zZVBhcmFtcyBfcmVzcG9uc2UgPSBuZXcgU2Nhbm5lclNjYW5SZXNwb25zZVBhcmFtcygpOwogICAgICAgICAgICBfcmVzcG9uc2UuaGFuZGxlID0gaGFuZGxlOwogICAgICAgICAgICBfcmVzcG9uc2UuZXJyID0gZXJyOwogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TZXJ2aWNlTWVzc2FnZSBfbWVzc2FnZSA9CiAgICAgICAgICAgICAgICAgICAgX3Jlc3BvbnNlLnNlcmlhbGl6ZVdpdGhIZWFkZXIoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtQ29yZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5NZXNzYWdlSGVhZGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0FOX09SRElOQUwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIuTUVTU0FHRV9JU19SRVNQT05TRV9GTEFHLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtUmVxdWVzdElkKSk7CiAgICAgICAgICAgIG1NZXNzYWdlUmVjZWl2ZXIuYWNjZXB0KF9tZXNzYWdlKTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGNsYXNzIFNjYW5uZXJTdG9wUGFyYW1zIGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuU3RydWN0IHsKICAgIAogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVFJVQ1RfU0laRSA9IDE2OwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXJbXSBWRVJTSU9OX0FSUkFZID0gbmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXJbXSB7bmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIoMTYsIDApfTsKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyIERFRkFVTFRfU1RSVUNUX0lORk8gPSBWRVJTSU9OX0FSUkFZWzBdOwogICAgCiAgICAgICAgcHVibGljIGludCBoOwogICAgCiAgICAgICAgcHJpdmF0ZSBTY2FubmVyU3RvcFBhcmFtcyhpbnQgdmVyc2lvbikgewogICAgICAgICAgICBzdXBlcihTVFJVQ1RfU0laRSwgdmVyc2lvbik7CiAgICAgICAgfQogICAgCiAgICAgICAgcHVibGljIFNjYW5uZXJTdG9wUGFyYW1zKCkgewogICAgICAgICAgICB0aGlzKDApOwogICAgICAgIH0KICAgIAogICAgICAgIHB1YmxpYyBzdGF0aWMgU2Nhbm5lclN0b3BQYXJhbXMgZGVzZXJpYWxpemUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBkZWNvZGUobmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIobWVzc2FnZSkpOwogICAgICAgIH0KICAgIAogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIHB1YmxpYyBzdGF0aWMgU2Nhbm5lclN0b3BQYXJhbXMgZGVjb2RlKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIgZGVjb2RlcjApIHsKICAgICAgICAgICAgaWYgKGRlY29kZXIwID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgbWFpbkRhdGFIZWFkZXIgPSBkZWNvZGVyMC5yZWFkQW5kVmFsaWRhdGVEYXRhSGVhZGVyKFZFUlNJT05fQVJSQVkpOwogICAgICAgICAgICBTY2FubmVyU3RvcFBhcmFtcyByZXN1bHQgPSBuZXcgU2Nhbm5lclN0b3BQYXJhbXMobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24pOwogICAgICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICAgICAgcmVzdWx0LmggPSBkZWNvZGVyMC5yZWFkSW50KDgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGZpbmFsIHZvaWQgZW5jb2RlKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcikgewogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIwID0gZW5jb2Rlci5nZXRFbmNvZGVyQXREYXRhT2Zmc2V0KERFRkFVTFRfU1RSVUNUX0lORk8pOwogICAgICAgICAgICBlbmNvZGVyMC5lbmNvZGUoaCwgOCk7CiAgICAgICAgfQogICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBPYmplY3QjZXF1YWxzKE9iamVjdCkKICAgICAgICAgKi8KICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iamVjdCkgewogICAgICAgICAgICBpZiAob2JqZWN0ID09IHRoaXMpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmplY3QuZ2V0Q2xhc3MoKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgU2Nhbm5lclN0b3BQYXJhbXMgb3RoZXIgPSAoU2Nhbm5lclN0b3BQYXJhbXMpIG9iamVjdDsKICAgICAgICAgICAgaWYgKHRoaXMuaCAhPSBvdGhlci5oKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAc2VlIE9iamVjdCNoYXNoQ29kZSgpCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgZmluYWwgaW50IHByaW1lID0gMzE7CiAgICAgICAgICAgIGludCByZXN1bHQgPSBwcmltZSArIGdldENsYXNzKCkuaGFzaENvZGUoKTsKICAgICAgICAgICAgcmVzdWx0ID0gcHJpbWUgKiByZXN1bHQgKyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5oYXNoQ29kZShoKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGZpbmFsIGNsYXNzIFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXMgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TdHJ1Y3QgewogICAgCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNUUlVDVF9TSVpFID0gMTY7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIFZFUlNJT05fQVJSQVkgPSBuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIHtuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcigxNiwgMCl9OwogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgREVGQVVMVF9TVFJVQ1RfSU5GTyA9IFZFUlNJT05fQVJSQVlbMF07CiAgICAKICAgICAgICBwdWJsaWMgRXJyb3IgZXJyOwogICAgCiAgICAgICAgcHJpdmF0ZSBTY2FubmVyU3RvcFJlc3BvbnNlUGFyYW1zKGludCB2ZXJzaW9uKSB7CiAgICAgICAgICAgIHN1cGVyKFNUUlVDVF9TSVpFLCB2ZXJzaW9uKTsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgU2Nhbm5lclN0b3BSZXNwb25zZVBhcmFtcygpIHsKICAgICAgICAgICAgdGhpcygwKTsKICAgICAgICB9CiAgICAKICAgICAgICBwdWJsaWMgc3RhdGljIFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXMgZGVzZXJpYWxpemUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBkZWNvZGUobmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIobWVzc2FnZSkpOwogICAgICAgIH0KICAgIAogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgICAgIHB1YmxpYyBzdGF0aWMgU2Nhbm5lclN0b3BSZXNwb25zZVBhcmFtcyBkZWNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMCkgewogICAgICAgICAgICBpZiAoZGVjb2RlcjAgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBtYWluRGF0YUhlYWRlciA9IGRlY29kZXIwLnJlYWRBbmRWYWxpZGF0ZURhdGFIZWFkZXIoVkVSU0lPTl9BUlJBWSk7CiAgICAgICAgICAgIFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXMgcmVzdWx0ID0gbmV3IFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXMobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24pOwogICAgICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMSA9IGRlY29kZXIwLnJlYWRQb2ludGVyKDgsIHRydWUpOwogICAgICAgICAgICAgICAgcmVzdWx0LmVyciA9IEVycm9yLmRlY29kZShkZWNvZGVyMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyKSB7CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcjAgPSBlbmNvZGVyLmdldEVuY29kZXJBdERhdGFPZmZzZXQoREVGQVVMVF9TVFJVQ1RfSU5GTyk7CiAgICAgICAgICAgIGVuY29kZXIwLmVuY29kZShlcnIsIDgsIHRydWUpOwogICAgICAgIH0KICAgIAogICAgICAgIC8qKgogICAgICAgICAqIEBzZWUgT2JqZWN0I2VxdWFscyhPYmplY3QpCiAgICAgICAgICovCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmplY3QpIHsKICAgICAgICAgICAgaWYgKG9iamVjdCA9PSB0aGlzKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgaWYgKGdldENsYXNzKCkgIT0gb2JqZWN0LmdldENsYXNzKCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXMgb3RoZXIgPSAoU2Nhbm5lclN0b3BSZXNwb25zZVBhcmFtcykgb2JqZWN0OwogICAgICAgICAgICBpZiAoIW9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmVxdWFscyh0aGlzLmVyciwgb3RoZXIuZXJyKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgCiAgICAgICAgLyoqCiAgICAgICAgICogQHNlZSBPYmplY3QjaGFzaENvZGUoKQogICAgICAgICAqLwogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICAgIGZpbmFsIGludCBwcmltZSA9IDMxOwogICAgICAgICAgICBpbnQgcmVzdWx0ID0gcHJpbWUgKyBnZXRDbGFzcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuaGFzaENvZGUoZXJyKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXNGb3J3YXJkVG9DYWxsYmFjayBleHRlbmRzIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlNpZGVFZmZlY3RGcmVlQ2xvc2VhYmxlCiAgICAgICAgICAgIGltcGxlbWVudHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZVJlY2VpdmVyIHsKICAgICAgICBwcml2YXRlIGZpbmFsIFNjYW5uZXIuU3RvcFJlc3BvbnNlIG1DYWxsYmFjazsKCiAgICAgICAgU2Nhbm5lclN0b3BSZXNwb25zZVBhcmFtc0ZvcndhcmRUb0NhbGxiYWNrKFNjYW5uZXIuU3RvcFJlc3BvbnNlIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIHRoaXMubUNhbGxiYWNrID0gY2FsbGJhY2s7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBhY2NlcHQob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TZXJ2aWNlTWVzc2FnZSBtZXNzYWdlV2l0aEhlYWRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXNTZXJ2aWNlTWVzc2FnZSgpOwogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlciBoZWFkZXIgPSBtZXNzYWdlV2l0aEhlYWRlci5nZXRIZWFkZXIoKTsKICAgICAgICAgICAgICAgIGlmICghaGVhZGVyLnZhbGlkYXRlSGVhZGVyKFNUT1BfT1JESU5BTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIuTUVTU0FHRV9JU19SRVNQT05TRV9GTEFHKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXMgcmVzcG9uc2UgPSBTY2FubmVyU3RvcFJlc3BvbnNlUGFyYW1zLmRlc2VyaWFsaXplKG1lc3NhZ2VXaXRoSGVhZGVyLmdldFBheWxvYWQoKSk7CiAgICAgICAgICAgICAgICBtQ2FsbGJhY2suY2FsbChyZXNwb25zZS5lcnIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gY2F0Y2ggKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXNQcm94eVRvUmVzcG9uZGVyIGltcGxlbWVudHMgU2Nhbm5lci5TdG9wUmVzcG9uc2UgewoKICAgICAgICBwcml2YXRlIGZpbmFsIG9yZy5jaHJvbWl1bS5tb2pvLnN5c3RlbS5Db3JlIG1Db3JlOwogICAgICAgIHByaXZhdGUgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZVJlY2VpdmVyIG1NZXNzYWdlUmVjZWl2ZXI7CiAgICAgICAgcHJpdmF0ZSBmaW5hbCBsb25nIG1SZXF1ZXN0SWQ7CgogICAgICAgIFNjYW5uZXJTdG9wUmVzcG9uc2VQYXJhbXNQcm94eVRvUmVzcG9uZGVyKAogICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uc3lzdGVtLkNvcmUgY29yZSwKICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VSZWNlaXZlciBtZXNzYWdlUmVjZWl2ZXIsCiAgICAgICAgICAgICAgICBsb25nIHJlcXVlc3RJZCkgewogICAgICAgICAgICBtQ29yZSA9IGNvcmU7CiAgICAgICAgICAgIG1NZXNzYWdlUmVjZWl2ZXIgPSBtZXNzYWdlUmVjZWl2ZXI7CiAgICAgICAgICAgIG1SZXF1ZXN0SWQgPSByZXF1ZXN0SWQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCBjYWxsKEVycm9yIGVycikgewogICAgICAgICAgICBTY2FubmVyU3RvcFJlc3BvbnNlUGFyYW1zIF9yZXNwb25zZSA9IG5ldyBTY2FubmVyU3RvcFJlc3BvbnNlUGFyYW1zKCk7CiAgICAgICAgICAgIF9yZXNwb25zZS5lcnIgPSBlcnI7CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLlNlcnZpY2VNZXNzYWdlIF9tZXNzYWdlID0KICAgICAgICAgICAgICAgICAgICBfcmVzcG9uc2Uuc2VyaWFsaXplV2l0aEhlYWRlcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1Db3JlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLk1lc3NhZ2VIZWFkZXIoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUT1BfT1JESU5BTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZUhlYWRlci5NRVNTQUdFX0lTX1JFU1BPTlNFX0ZMQUcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1SZXF1ZXN0SWQpKTsKICAgICAgICAgICAgbU1lc3NhZ2VSZWNlaXZlci5hY2NlcHQoX21lc3NhZ2UpOwogICAgICAgIH0KICAgIH0KCn0KClBLAwQUAAAAAABZdidIr2GZtOoiAADqIgAAIAAAAGlvL3YvbW9qby9kaXNjb3ZlcnkvU2VydmljZS5qYXZhLy8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIFRoaXMgZmlsZSBpcyBhdXRvZ2VuZXJhdGVkIGJ5OgovLyAgICAgbW9qby9wdWJsaWMvdG9vbHMvYmluZGluZ3MvbW9qb21fYmluZGluZ3NfZ2VuZXJhdG9yLnB5Ci8vIEZvcjoKLy8gICAgIG1vam9tL3ZhbmFkaXVtL2Rpc2NvdmVyeS5tb2pvbQovLwoKcGFja2FnZSBpby52Lm1vam8uZGlzY292ZXJ5OwoKcHVibGljIGZpbmFsIGNsYXNzIFNlcnZpY2UgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5TdHJ1Y3QgewoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVFJVQ1RfU0laRSA9IDQ4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIFZFUlNJT05fQVJSQVkgPSBuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcltdIHtuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlcig0OCwgMCl9OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBERUZBVUxUX1NUUlVDVF9JTkZPID0gVkVSU0lPTl9BUlJBWVswXTsKCiAgICBwdWJsaWMgU3RyaW5nIGluc3RhbmNlSWQ7CiAgICBwdWJsaWMgU3RyaW5nIGluc3RhbmNlTmFtZTsKICAgIHB1YmxpYyBTdHJpbmcgaW50ZXJmYWNlTmFtZTsKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPFN0cmluZywgU3RyaW5nPiBhdHRyczsKICAgIHB1YmxpYyBTdHJpbmdbXSBhZGRyczsKCiAgICBwcml2YXRlIFNlcnZpY2UoaW50IHZlcnNpb24pIHsKICAgICAgICBzdXBlcihTVFJVQ1RfU0laRSwgdmVyc2lvbik7CiAgICB9CgogICAgcHVibGljIFNlcnZpY2UoKSB7CiAgICAgICAgdGhpcygwKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFNlcnZpY2UgZGVzZXJpYWxpemUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuTWVzc2FnZSBtZXNzYWdlKSB7CiAgICAgICAgcmV0dXJuIGRlY29kZShuZXcgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlcihtZXNzYWdlKSk7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICBwdWJsaWMgc3RhdGljIFNlcnZpY2UgZGVjb2RlKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRlY29kZXIgZGVjb2RlcjApIHsKICAgICAgICBpZiAoZGVjb2RlcjAgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlciBtYWluRGF0YUhlYWRlciA9IGRlY29kZXIwLnJlYWRBbmRWYWxpZGF0ZURhdGFIZWFkZXIoVkVSU0lPTl9BUlJBWSk7CiAgICAgICAgU2VydmljZSByZXN1bHQgPSBuZXcgU2VydmljZShtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbik7CiAgICAgICAgaWYgKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uID49IDApIHsKICAgICAgICAgICAgcmVzdWx0Lmluc3RhbmNlSWQgPSBkZWNvZGVyMC5yZWFkU3RyaW5nKDgsIHRydWUpOwogICAgICAgIH0KICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICByZXN1bHQuaW5zdGFuY2VOYW1lID0gZGVjb2RlcjAucmVhZFN0cmluZygxNiwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChtYWluRGF0YUhlYWRlci5lbGVtZW50c09yVmVyc2lvbiA+PSAwKSB7CiAgICAgICAgICAgIHJlc3VsdC5pbnRlcmZhY2VOYW1lID0gZGVjb2RlcjAucmVhZFN0cmluZygyNCwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICBpZiAobWFpbkRhdGFIZWFkZXIuZWxlbWVudHNPclZlcnNpb24gPj0gMCkgewogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EZWNvZGVyIGRlY29kZXIxID0gZGVjb2RlcjAucmVhZFBvaW50ZXIoMzIsIHRydWUpOwogICAgICAgICAgICBpZiAoZGVjb2RlcjEgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmVzdWx0LmF0dHJzID0gbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGRlY29kZXIxLnJlYWREYXRhSGVhZGVyRm9yTWFwKCk7CiAgICAgICAgICAgICAgICBTdHJpbmdbXSBrZXlzMDsKICAgICAgICAgICAgICAgIFN0cmluZ1tdIHZhbHVlczA7CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMiA9IGRlY29kZXIxLnJlYWRQb2ludGVyKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIuSEVBREVSX1NJWkUsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgc2kyID0gZGVjb2RlcjIucmVhZERhdGFIZWFkZXJGb3JQb2ludGVyQXJyYXkob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuVU5TUEVDSUZJRURfQVJSQVlfTEVOR1RIKTsKICAgICAgICAgICAgICAgICAgICAgICAga2V5czAgPSBuZXcgU3RyaW5nW3NpMi5lbGVtZW50c09yVmVyc2lvbl07CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGkyID0gMDsgaTIgPCBzaTIuZWxlbWVudHNPclZlcnNpb247ICsraTIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleXMwW2kyXSA9IGRlY29kZXIyLnJlYWRTdHJpbmcob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlci5IRUFERVJfU0laRSArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLlBPSU5URVJfU0laRSAqIGkyLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMiA9IGRlY29kZXIxLnJlYWRQb2ludGVyKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIuSEVBREVSX1NJWkUgKyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5QT0lOVEVSX1NJWkUsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgc2kyID0gZGVjb2RlcjIucmVhZERhdGFIZWFkZXJGb3JQb2ludGVyQXJyYXkoa2V5czAubGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzMCA9IG5ldyBTdHJpbmdbc2kyLmVsZW1lbnRzT3JWZXJzaW9uXTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaTIgPSAwOyBpMiA8IHNpMi5lbGVtZW50c09yVmVyc2lvbjsgKytpMikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzMFtpMl0gPSBkZWNvZGVyMi5yZWFkU3RyaW5nKG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIuSEVBREVSX1NJWkUgKyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5QT0lOVEVSX1NJWkUgKiBpMiwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmVzdWx0LmF0dHJzID0gbmV3IGphdmEudXRpbC5IYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaW5kZXgwID0gMDsgaW5kZXgwIDwga2V5czAubGVuZ3RoOyArK2luZGV4MCkgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hdHRycy5wdXQoa2V5czBbaW5kZXgwXSwgIHZhbHVlczBbaW5kZXgwXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKG1haW5EYXRhSGVhZGVyLmVsZW1lbnRzT3JWZXJzaW9uID49IDApIHsKICAgICAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGVjb2RlciBkZWNvZGVyMSA9IGRlY29kZXIwLnJlYWRQb2ludGVyKDQwLCBmYWxzZSk7CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkRhdGFIZWFkZXIgc2kxID0gZGVjb2RlcjEucmVhZERhdGFIZWFkZXJGb3JQb2ludGVyQXJyYXkob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuVU5TUEVDSUZJRURfQVJSQVlfTEVOR1RIKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5hZGRycyA9IG5ldyBTdHJpbmdbc2kxLmVsZW1lbnRzT3JWZXJzaW9uXTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkxID0gMDsgaTEgPCBzaTEuZWxlbWVudHNPclZlcnNpb247ICsraTEpIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQuYWRkcnNbaTFdID0gZGVjb2RlcjEucmVhZFN0cmluZyhvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyLkhFQURFUl9TSVpFICsgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuUE9JTlRFUl9TSVpFICogaTEsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgQE92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgZmluYWwgdm9pZCBlbmNvZGUob3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyKSB7CiAgICAgICAgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRW5jb2RlciBlbmNvZGVyMCA9IGVuY29kZXIuZ2V0RW5jb2RlckF0RGF0YU9mZnNldChERUZBVUxUX1NUUlVDVF9JTkZPKTsKICAgICAgICBlbmNvZGVyMC5lbmNvZGUoaW5zdGFuY2VJZCwgOCwgdHJ1ZSk7CiAgICAgICAgZW5jb2RlcjAuZW5jb2RlKGluc3RhbmNlTmFtZSwgMTYsIHRydWUpOwogICAgICAgIGVuY29kZXIwLmVuY29kZShpbnRlcmZhY2VOYW1lLCAyNCwgZmFsc2UpOwogICAgICAgIGlmIChhdHRycyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuY29kZXIwLmVuY29kZU51bGxQb2ludGVyKDMyLCB0cnVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIxID0gZW5jb2RlcjAuZW5jb2RlckZvck1hcCgzMik7CiAgICAgICAgICAgIGludCBzaXplMCA9IGF0dHJzLnNpemUoKTsKICAgICAgICAgICAgU3RyaW5nW10ga2V5czAgPSBuZXcgU3RyaW5nW3NpemUwXTsKICAgICAgICAgICAgU3RyaW5nW10gdmFsdWVzMCA9IG5ldyBTdHJpbmdbc2l6ZTBdOwogICAgICAgICAgICBpbnQgaW5kZXgwID0gMDsKICAgICAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PFN0cmluZywgU3RyaW5nPiBlbnRyeTAgOiBhdHRycy5lbnRyeVNldCgpKSB7CiAgICAgICAgICAgICAgICBrZXlzMFtpbmRleDBdID0gZW50cnkwLmdldEtleSgpOwogICAgICAgICAgICAgICAgdmFsdWVzMFtpbmRleDBdID0gZW50cnkwLmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICArK2luZGV4MDsKICAgICAgICAgICAgfQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIyID0gZW5jb2RlcjEuZW5jb2RlUG9pbnRlckFycmF5KGtleXMwLmxlbmd0aCwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlci5IRUFERVJfU0laRSwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuVU5TUEVDSUZJRURfQVJSQVlfTEVOR1RIKTsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkxID0gMDsgaTEgPCBrZXlzMC5sZW5ndGg7ICsraTEpIHsKICAgICAgICAgICAgICAgICAgICBlbmNvZGVyMi5lbmNvZGUoa2V5czBbaTFdLCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyLkhFQURFUl9TSVpFICsgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuUE9JTlRFUl9TSVpFICogaTEsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5FbmNvZGVyIGVuY29kZXIyID0gZW5jb2RlcjEuZW5jb2RlUG9pbnRlckFycmF5KHZhbHVlczAubGVuZ3RoLCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyLkhFQURFUl9TSVpFICsgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuUE9JTlRFUl9TSVpFLCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5CaW5kaW5nc0hlbHBlci5VTlNQRUNJRklFRF9BUlJBWV9MRU5HVEgpOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaTEgPSAwOyBpMSA8IHZhbHVlczAubGVuZ3RoOyArK2kxKSB7CiAgICAgICAgICAgICAgICAgICAgZW5jb2RlcjIuZW5jb2RlKHZhbHVlczBbaTFdLCBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5EYXRhSGVhZGVyLkhFQURFUl9TSVpFICsgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuUE9JTlRFUl9TSVpFICogaTEsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoYWRkcnMgPT0gbnVsbCkgewogICAgICAgICAgICBlbmNvZGVyMC5lbmNvZGVOdWxsUG9pbnRlcig0MCwgZmFsc2UpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkVuY29kZXIgZW5jb2RlcjEgPSBlbmNvZGVyMC5lbmNvZGVQb2ludGVyQXJyYXkoYWRkcnMubGVuZ3RoLCA0MCwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuVU5TUEVDSUZJRURfQVJSQVlfTEVOR1RIKTsKICAgICAgICAgICAgZm9yIChpbnQgaTAgPSAwOyBpMCA8IGFkZHJzLmxlbmd0aDsgKytpMCkgewogICAgICAgICAgICAgICAgZW5jb2RlcjEuZW5jb2RlKGFkZHJzW2kwXSwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuRGF0YUhlYWRlci5IRUFERVJfU0laRSArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLlBPSU5URVJfU0laRSAqIGkwLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAc2VlIE9iamVjdCNlcXVhbHMoT2JqZWN0KQogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqZWN0KSB7CiAgICAgICAgaWYgKG9iamVjdCA9PSB0aGlzKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAob2JqZWN0ID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoZ2V0Q2xhc3MoKSAhPSBvYmplY3QuZ2V0Q2xhc3MoKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIFNlcnZpY2Ugb3RoZXIgPSAoU2VydmljZSkgb2JqZWN0OwogICAgICAgIGlmICghb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuZXF1YWxzKHRoaXMuaW5zdGFuY2VJZCwgb3RoZXIuaW5zdGFuY2VJZCkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIW9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmVxdWFscyh0aGlzLmluc3RhbmNlTmFtZSwgb3RoZXIuaW5zdGFuY2VOYW1lKSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuZXF1YWxzKHRoaXMuaW50ZXJmYWNlTmFtZSwgb3RoZXIuaW50ZXJmYWNlTmFtZSkpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIW9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmVxdWFscyh0aGlzLmF0dHJzLCBvdGhlci5hdHRycykpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIWphdmEudXRpbC5BcnJheXMuZGVlcEVxdWFscyh0aGlzLmFkZHJzLCBvdGhlci5hZGRycykpCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBzZWUgT2JqZWN0I2hhc2hDb2RlKCkKICAgICAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGZpbmFsIGludCBwcmltZSA9IDMxOwogICAgICAgIGludCByZXN1bHQgPSBwcmltZSArIGdldENsYXNzKCkuaGFzaENvZGUoKTsKICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGluc3RhbmNlSWQpOwogICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuaGFzaENvZGUoaW5zdGFuY2VOYW1lKTsKICAgICAgICByZXN1bHQgPSBwcmltZSAqIHJlc3VsdCArIG9yZy5jaHJvbWl1bS5tb2pvLmJpbmRpbmdzLkJpbmRpbmdzSGVscGVyLmhhc2hDb2RlKGludGVyZmFjZU5hbWUpOwogICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQmluZGluZ3NIZWxwZXIuaGFzaENvZGUoYXR0cnMpOwogICAgICAgIHJlc3VsdCA9IHByaW1lICogcmVzdWx0ICsgamF2YS51dGlsLkFycmF5cy5kZWVwSGFzaENvZGUoYWRkcnMpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9Cn0KClBLAwQUAAAAAABZdidIIclOPY4DAACOAwAAIAAAAGlvL3YvbW9qby9kaXNjb3ZlcnkvU2Nhbm5lci5qYXZhLy8gQ29weXJpZ2h0IDIwMTQgVGhlIENocm9taXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KCi8vIFRoaXMgZmlsZSBpcyBhdXRvZ2VuZXJhdGVkIGJ5OgovLyAgICAgbW9qby9wdWJsaWMvdG9vbHMvYmluZGluZ3MvbW9qb21fYmluZGluZ3NfZ2VuZXJhdG9yLnB5Ci8vIEZvcjoKLy8gICAgIG1vam9tL3ZhbmFkaXVtL2Rpc2NvdmVyeS5tb2pvbQovLwoKcGFja2FnZSBpby52Lm1vam8uZGlzY292ZXJ5OwoKcHVibGljIGludGVyZmFjZSBTY2FubmVyIGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlIHsKCiAgICBwdWJsaWMgaW50ZXJmYWNlIFByb3h5IGV4dGVuZHMgU2Nhbm5lciwgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuSW50ZXJmYWNlLlByb3h5IHsKICAgIH0KCiAgICBOYW1lZE1hbmFnZXI8U2Nhbm5lciwgU2Nhbm5lci5Qcm94eT4gTUFOQUdFUiA9IFNjYW5uZXJfSW50ZXJuYWwuTUFOQUdFUjsKCiAgICB2b2lkIHNjYW4oU3RyaW5nIHF1ZXJ5LCBTY2FuSGFuZGxlciBzY2FuSGFuZGxlciwgU2NhblJlc3BvbnNlIGNhbGxiYWNrKTsKICAgIGludGVyZmFjZSBTY2FuUmVzcG9uc2UgZXh0ZW5kcyBvcmcuY2hyb21pdW0ubW9qby5iaW5kaW5ncy5DYWxsYmFja3MuQ2FsbGJhY2syPEludGVnZXIsIEVycm9yPiB7IH0KCiAgICB2b2lkIHN0b3AoaW50IGgsIFN0b3BSZXNwb25zZSBjYWxsYmFjayk7CiAgICBpbnRlcmZhY2UgU3RvcFJlc3BvbnNlIGV4dGVuZHMgb3JnLmNocm9taXVtLm1vam8uYmluZGluZ3MuQ2FsbGJhY2tzLkNhbGxiYWNrMTxFcnJvcj4geyB9Cn0KClBLAQIUAxQAAAAAAFl2J0gUVak0qAIAAKgCAAAkAAAAAAAAAAAAAACggQAAAABpby92L21vam8vZGlzY292ZXJ5L1NjYW5IYW5kbGVyLmphdmFQSwECFAMUAAAAAABZdidIePGi6MErAADBKwAALQAAAAAAAAAAAAAAoIHqAgAAaW8vdi9tb2pvL2Rpc2NvdmVyeS9TY2FuSGFuZGxlcl9JbnRlcm5hbC5qYXZhUEsBAhQDFAAAAAAAWXYnSDRkQYbqDAAA6gwAAB4AAAAAAAAAAAAAAKCB9i4AAGlvL3YvbW9qby9kaXNjb3ZlcnkvRXJyb3IuamF2YVBLAQIUAxQAAAAAAFl2J0jwvBKzeGMAAHhjAAAsAAAAAAAAAAAAAACggRw8AABpby92L21vam8vZGlzY292ZXJ5L0FkdmVydGlzZXJfSW50ZXJuYWwuamF2YVBLAQIUAxQAAAAAAFl2J0hBzGQFswMAALMDAAAjAAAAAAAAAAAAAACggd6fAABpby92L21vam8vZGlzY292ZXJ5L0FkdmVydGlzZXIuamF2YVBLAQIUAxQAAAAAAFl2J0j2W1u701oAANNaAAApAAAAAAAAAAAAAACggdKjAABpby92L21vam8vZGlzY292ZXJ5L1NjYW5uZXJfSW50ZXJuYWwuamF2YVBLAQIUAxQAAAAAAFl2J0ivYZm06iIAAOoiAAAgAAAAAAAAAAAAAACggez+AABpby92L21vam8vZGlzY292ZXJ5L1NlcnZpY2UuamF2YVBLAQIUAxQAAAAAAFl2J0ghyU49jgMAAI4DAAAgAAAAAAAAAAAAAACggRQiAQBpby92L21vam8vZGlzY292ZXJ5L1NjYW5uZXIuamF2YVBLBQYAAAAACAAIAJcCAADgJQEAAAA=