cGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLnZpZXcudHJlZTsKLyoqCiAqIENvcHlyaWdodCAoYykgMjAwMyBJQk0gQ29ycG9yYXRpb24gYW5kIG90aGVycy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqLwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JQWRhcHRhYmxlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLlBsYXRmb3JtOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UucmVzb3VyY2UuSW1hZ2VEZXNjcmlwdG9yOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklFbGVtZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJDb25maWd1cmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLlNlcnZlckNvcmU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLlNlcnZlckltYWdlUmVzb3VyY2U7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLlNlcnZlclRyZWVDb250ZW50UHJvdmlkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLlNlcnZlclVJUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVNoYXJlZEltYWdlczsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLlBsYXRmb3JtVUk7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5pZGUuSURFOwppbXBvcnQgb3JnLmVjbGlwc2UudWkubW9kZWwuSVdvcmtiZW5jaEFkYXB0ZXI7CgovKioKICogCiAqLwpwdWJsaWMgY2xhc3MgVGV4dFJlc291cmNlQWRhcHRlciBpbXBsZW1lbnRzIElBZGFwdGFibGUsIElXb3JrYmVuY2hBZGFwdGVyLCBJU2VydmVyRWxlbWVudFRhZyB7Cglwcm90ZWN0ZWQgT2JqZWN0IHBhcmVudDsKCXByb3RlY3RlZCBieXRlIHRoaXNTdHlsZTsKCQoJcHVibGljIHN0YXRpYyBJRWxlbWVudCBkZWxldGVkOwoJCglwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgU1RZTEVfU0VSVkVSUyA9IDA7CglwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgU1RZTEVfQ09ORklHVVJBVElPTlMgPSAxOwoJLy9wdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgU1RZTEVfU0VSVkVSU19BTkRfQ09ORklHVVJBVElPTlMgPSAyOwoJLy9wdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgU1RZTEVfTk9fQ09ORklHVVJBVElPTiA9IDM7CglwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgU1RZTEVfTk9fTU9EVUxFUyA9IDQ7CglwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgU1RZTEVfTk9fU0VSVkVSUyA9IDU7CglwdWJsaWMgZmluYWwgc3RhdGljIGJ5dGUgU1RZTEVfTE9PU0VfQ09ORklHVVJBVElPTlMgPSA2OwoKCXB1YmxpYyBUZXh0UmVzb3VyY2VBZGFwdGVyKE9iamVjdCBwYXJlbnQsIGJ5dGUgdGhpc1N0eWxlKSB7CgkJdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CgkJdGhpcy50aGlzU3R5bGUgPSB0aGlzU3R5bGU7Cgl9CgkKCXB1YmxpYyBieXRlIGdldFN0eWxlKCkgewoJCXJldHVybiB0aGlzU3R5bGU7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFN0eWxlKGJ5dGUgYikgewoJCXRoaXNTdHlsZSA9IGI7Cgl9CgoJLyoKCSAqIEBzZWUgSUFkYXB0YWJsZSNnZXRBZGFwdGVyKENsYXNzKQoJICovCglwdWJsaWMgT2JqZWN0IGdldEFkYXB0ZXIoQ2xhc3MgYWRhcHRlcikgewoJCWlmIChhZGFwdGVyLmVxdWFscyhJQWRhcHRhYmxlLmNsYXNzKSkKCQkJcmV0dXJuIHRoaXM7CgkJZWxzZSBpZiAoYWRhcHRlci5lcXVhbHMoSVdvcmtiZW5jaEFkYXB0ZXIuY2xhc3MpKQoJCQlyZXR1cm4gdGhpczsKCQllbHNlCgkJCXJldHVybiBQbGF0Zm9ybS5nZXRBZGFwdGVyTWFuYWdlcigpLmdldEFkYXB0ZXIodGhpcywgYWRhcHRlcik7Cgl9CgoJLyoKCSAqIEBzZWUgSVdvcmtiZW5jaEFkYXB0ZXIjZ2V0Q2hpbGRyZW4oT2JqZWN0KQoJICovCglwdWJsaWMgT2JqZWN0W10gZ2V0Q2hpbGRyZW4oT2JqZWN0IG8pIHsKCQlpZiAodGhpc1N0eWxlID09IFNUWUxFX05PX01PRFVMRVMgfHwgdGhpc1N0eWxlID09IFNUWUxFX05PX1NFUlZFUlMpCgkJCXJldHVybiBuZXcgT2JqZWN0WzBdOwoJCWlmICh0aGlzU3R5bGUgPT0gU1RZTEVfTE9PU0VfQ09ORklHVVJBVElPTlMpIHsKCQkJSVNlcnZlckNvbmZpZ3VyYXRpb25bXSBsb29zZUNmZyA9IFNlcnZlclRyZWVDb250ZW50UHJvdmlkZXIuZ2V0TG9vc2VDb25maWd1cmF0aW9ucygpOwoJCQlpbnQgc2l6ZSA9IGxvb3NlQ2ZnLmxlbmd0aDsKCQkJT2JqZWN0W10gb2JqID0gbmV3IE9iamVjdFtzaXplXTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCW9ialtpXSA9IG5ldyBTZXJ2ZXJFbGVtZW50QWRhcHRlcih0aGlzLCBsb29zZUNmZ1tpXSk7CgkJCX0KCQkJCgkJCXJldHVybiBvYmo7CgkJfQoJCS8qZWxzZSBpZiAodGhpc1N0eWxlID09IFNUWUxFX1NFUlZFUlNfQU5EX0NPTkZJR1VSQVRJT05TKSAKCQkJcmV0dXJuIG5ldyBPYmplY3RbXSB7CgkJCQluZXcgVGV4dFJlc291cmNlQWRhcHRlcih0aGlzLCBTVFlMRV9TRVJWRVJTKSwKCQkJCW5ldyBUZXh0UmVzb3VyY2VBZGFwdGVyKHRoaXMsIFNUWUxFX0NPTkZJR1VSQVRJT05TKQoJCQl9OyovCgoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gbnVsbDsKCQlpZiAodGhpc1N0eWxlID09IFNUWUxFX1NFUlZFUlMpCgkJCWl0ZXJhdG9yID0gU2VydmVyQ29yZS5nZXRSZXNvdXJjZU1hbmFnZXIoKS5nZXRTZXJ2ZXJzKCkuaXRlcmF0b3IoKTsKCQllbHNlIGlmICh0aGlzU3R5bGUgPT0gU1RZTEVfQ09ORklHVVJBVElPTlMpCgkJCWl0ZXJhdG9yID0gU2VydmVyQ29yZS5nZXRSZXNvdXJjZU1hbmFnZXIoKS5nZXRTZXJ2ZXJDb25maWd1cmF0aW9ucygpLml0ZXJhdG9yKCk7CgoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlFbGVtZW50IHJlc291cmNlID0gKElFbGVtZW50KSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmIChyZXNvdXJjZSAhPSBkZWxldGVkKQoJCQkJbGlzdC5hZGQobmV3IFNlcnZlckVsZW1lbnRBZGFwdGVyKHRoaXMsIHJlc291cmNlKSk7CgkJfQoJCXJldHVybiBsaXN0LnRvQXJyYXkoKTsKCX0KCgkvKgoJICogQHNlZSBJV29ya2JlbmNoQWRhcHRlciNnZXRJbWFnZURlc2NyaXB0b3IoT2JqZWN0KQoJICovCglwdWJsaWMgSW1hZ2VEZXNjcmlwdG9yIGdldEltYWdlRGVzY3JpcHRvcihPYmplY3Qgb2JqZWN0KSB7CgkJaWYgKHRoaXNTdHlsZSA9PSBTVFlMRV9TRVJWRVJTKQoJCQlyZXR1cm4gU2VydmVySW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoU2VydmVySW1hZ2VSZXNvdXJjZS5JTUdfU0VSVkVSX0ZPTERFUik7CgkJZWxzZSBpZiAodGhpc1N0eWxlID09IFNUWUxFX0NPTkZJR1VSQVRJT05TIHx8IHRoaXNTdHlsZSA9PSBTVFlMRV9MT09TRV9DT05GSUdVUkFUSU9OUykKCQkJcmV0dXJuIFNlcnZlckltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKFNlcnZlckltYWdlUmVzb3VyY2UuSU1HX1NFUlZFUl9DT05GSUdVUkFUSU9OX0ZPTERFUik7CgkJLy9lbHNlIGlmICh0aGlzU3R5bGUgPT0gU1RZTEVfU0VSVkVSU19BTkRfQ09ORklHVVJBVElPTlMpCgkJLy8JcmV0dXJuIFNlcnZlckltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKFNlcnZlckltYWdlUmVzb3VyY2UuSU1HX1NFUlZFUl9QUk9KRUNUKTsKCQkvL2Vsc2UgaWYgKHRoaXNTdHlsZSA9PSBTVFlMRV9OT19DT05GSUdVUkFUSU9OKQoJCS8vCXJldHVybiBTZXJ2ZXJJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihTZXJ2ZXJJbWFnZVJlc291cmNlLklNR19TRVJWRVJfQ09ORklHVVJBVElPTl9OT05FKTsKCQllbHNlIGlmICh0aGlzU3R5bGUgPT0gU1RZTEVfTk9fTU9EVUxFUykgewoJCQlJU2hhcmVkSW1hZ2VzIHNoYXJlZEltYWdlcyA9IFBsYXRmb3JtVUkuZ2V0V29ya2JlbmNoKCkuZ2V0U2hhcmVkSW1hZ2VzKCk7CgkJCXJldHVybiBzaGFyZWRJbWFnZXMuZ2V0SW1hZ2VEZXNjcmlwdG9yKElERS5TaGFyZWRJbWFnZXMuSU1HX09CSl9QUk9KRUNUKTsKCQl9CgkJZWxzZSBpZiAodGhpc1N0eWxlID09IFNUWUxFX05PX1NFUlZFUlMpCgkJCXJldHVybiBTZXJ2ZXJJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihTZXJ2ZXJJbWFnZVJlc291cmNlLklNR19TRVJWRVJfQ09ORklHVVJBVElPTl9NSVNTSU5HKTsKCQllbHNlCgkJCXJldHVybiBudWxsOwoJfQoKCS8qCgkgKiBAc2VlIElXb3JrYmVuY2hBZGFwdGVyI2dldExhYmVsKE9iamVjdCkKCSAqLwoJcHVibGljIFN0cmluZyBnZXRMYWJlbChPYmplY3QgbykgewoJCWlmICh0aGlzU3R5bGUgPT0gU1RZTEVfU0VSVkVSUykKCQkJcmV0dXJuIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIldmlld1NlcnZlcnMiKTsKCQllbHNlIGlmICh0aGlzU3R5bGUgPT0gU1RZTEVfQ09ORklHVVJBVElPTlMpCgkJCXJldHVybiBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXZpZXdDb25maWd1cmF0aW9ucyIpOwoJCS8vZWxzZSBpZiAodGhpc1N0eWxlID09IFNUWUxFX1NFUlZFUlNfQU5EX0NPTkZJR1VSQVRJT05TKQoJCS8vCXJldHVybiAiU2VydmVyIEluZm8iOwoJCS8vZWxzZSBpZiAodGhpc1N0eWxlID09IFNUWUxFX05PX0NPTkZJR1VSQVRJT04pCgkJLy8JcmV0dXJuICJObyBjb25maWd1cmF0aW9uIjsKCQllbHNlIGlmICh0aGlzU3R5bGUgPT0gU1RZTEVfTk9fTU9EVUxFUykKCQkJcmV0dXJuIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIldmlld05vTW9kdWxlcyIpOwoJCWVsc2UgaWYgKHRoaXNTdHlsZSA9PSBTVFlMRV9OT19TRVJWRVJTKQoJCQlyZXR1cm4gU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV2aWV3Q29uZmlndXJhdGlvblVudXNlZCIpOwoJCWVsc2UgaWYgKHRoaXNTdHlsZSA9PSBTVFlMRV9MT09TRV9DT05GSUdVUkFUSU9OUykKCQkJcmV0dXJuIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIldmlld0xvb3NlQ29uZmlndXJhdGlvbnMiKTsKCQllbHNlCgkJCXJldHVybiAibi9hIjsKCX0KCgkvKgoJICogQHNlZSBJV29ya2JlbmNoQWRhcHRlciNnZXRQYXJlbnQoT2JqZWN0KQoJICovCglwdWJsaWMgT2JqZWN0IGdldFBhcmVudChPYmplY3QgbykgewoJCXJldHVybiBwYXJlbnQ7Cgl9CgkKCXB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CgkJaWYgKCEob2JqIGluc3RhbmNlb2YgVGV4dFJlc291cmNlQWRhcHRlcikpCQoJCQlyZXR1cm4gZmFsc2U7CgkJCgkJVGV4dFJlc291cmNlQWRhcHRlciBhZGFwdGVyID0gKFRleHRSZXNvdXJjZUFkYXB0ZXIpIG9iajsKCQlyZXR1cm4gKGFkYXB0ZXIuZ2V0U3R5bGUoKSA9PSB0aGlzU3R5bGUpOwoJfQoJCglwdWJsaWMgaW50IGhhc2hDb2RlKCkgewoJCXJldHVybiB0aGlzU3R5bGU7Cgl9Cn0K