LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBHb3JrZW0gRXJjYW4gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE5hY2kgTS4gRGFpCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCiAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAogKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCiAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBFdGVyYXRpb24gQmlsaXNpbSBBLlMuICBGb3IgbW9yZQogKiBpbmZvcm1hdGlvbiBvbiBldGVyYXRpb24sIHBsZWFzZSBzZWUKICogPGh0dHA6Ly93d3cuZXRlcmF0aW9uLmNvbS8+LgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuZ2VuZXJpYy5pbnRlcm5hbC5jb3JlOwoKaW1wb3J0IGphdmEubmV0LlVSTDsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUHJvamVjdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5Db3JlRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQYXRoOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1czsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5OdWxsUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLlBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5EZWJ1Z0V2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5EZWJ1Z1BsdWdpbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSURlYnVnRXZlbnRTZXRMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaDsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLklMYXVuY2hDb25maWd1cmF0aW9uVHlwZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weTsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaE1hbmFnZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLm1vZGVsLklQcm9jZXNzOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcudWkuSURlYnVnVUlDb25zdGFudHM7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLklKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSVJ1bnRpbWVDbGFzc3BhdGhFbnRyeTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSVZNSW5zdGFsbDsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSmF2YVJ1bnRpbWU7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuY29yZS5Db3JlUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmludGVybmFsLnhtbC5DbGFzc3BhdGhJdGVtOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmludGVybmFsLnhtbC5TZXJ2ZXJUeXBlRGVmaW5pdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuZ2VuZXJpYy5tb2R1bGVzLkoyZWVTcGVjTW9kdWxlRmFjdG9yeURlbGVnYXRlOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5qMmVlLklXZWJNb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyQ29uZmlndXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyU3RhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVRhc2s7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyQ29yZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGVFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlRmFjdG9yeUV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb25pdG9yYWJsZVNlcnZlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JUHVibGlzaGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyUG9ydDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU3RhcnRhYmxlU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklVUkxQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5yZXNvdXJjZXMuSU1vZHVsZVJlc291cmNlRGVsdGE7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUudXRpbC5TZXJ2ZXJQb3J0OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLnV0aWwuU29ja2V0VXRpbDsKCi8qKgogKiBHZW5lcmljIFhNTCBiYXNlZCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24uCiAqIAogKiBAYXV0aG9yIEdvcmtlbSBFcmNhbgogKi8KcHVibGljIGNsYXNzIEdlbmVyaWNTZXJ2ZXIgaW1wbGVtZW50cyBJU2VydmVyRGVsZWdhdGUsIElTdGFydGFibGVTZXJ2ZXIsIElNb25pdG9yYWJsZVNlcnZlcixJVVJMUHJvdmlkZXIgewoJcHJpdmF0ZSBJU2VydmVyU3RhdGUgZkxpdmVTZXJ2ZXI7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9TVE9QID0gInN0b3Atc2VydmVyIjsKCQoJLy8gdGhlIHRocmVhZCB1c2VkIHRvIHBpbmcgdGhlIHNlcnZlciB0byBjaGVjayBmb3Igc3RhcnR1cAoJcHJvdGVjdGVkIHRyYW5zaWVudCBQaW5nVGhyZWFkIHBpbmcgPSBudWxsOwoJcHJvdGVjdGVkIHRyYW5zaWVudCBJUHJvY2VzcyBwcm9jZXNzOwoJcHJvdGVjdGVkIHRyYW5zaWVudCBJRGVidWdFdmVudFNldExpc3RlbmVyIHByb2Nlc3NMaXN0ZW5lcjsKCQoJcHJpdmF0ZSBTZXJ2ZXJUeXBlRGVmaW5pdGlvbiBmU2VydmVyRGVmaW5pdGlvbjsKCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjaW5pdGlhbGl6ZShvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlclN0YXRlKQoJICovCglwdWJsaWMgdm9pZCBpbml0aWFsaXplKElTZXJ2ZXJTdGF0ZSBsaXZlU2VydmVyKSB7CgkJdGhpcy5mTGl2ZVNlcnZlciA9IGxpdmVTZXJ2ZXI7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI2Rpc3Bvc2UoKQoJICovCglwdWJsaWMgdm9pZCBkaXNwb3NlKCkgewoJCXRoaXMuZkxpdmVTZXJ2ZXIgPSBudWxsOwoKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHByb2plY3QgcHVibGlzaGVyIHRoYXQgY2FuIGJlIHVzZWQgdG8KCSAqIHB1Ymxpc2ggdGhlIGdpdmVuIHByb2plY3QuCgkgKgoJICogQHBhcmFtIHByb2plY3Qgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3QKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklQcm9qZWN0UHVibGlzaGVyCgkgKi8KCXB1YmxpYyBJUHVibGlzaGVyIGdldFB1Ymxpc2hlcihMaXN0IHBhcmVudHMsIElNb2R1bGUgbW9kdWxlKSB7CgkJcmV0dXJuIG5ldyBBbnRQdWJsaXNoZXIocGFyZW50cywgbW9kdWxlLCB0aGlzLmdldFNlcnZlckRlZmluaXRpb24oKSk7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3VwZGF0ZUNvbmZpZ3VyYXRpb24oKQoJICovCglwdWJsaWMgdm9pZCB1cGRhdGVDb25maWd1cmF0aW9uKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgInVwZGF0ZUNvbmZpZ3VyYXRpb24iICsgdGhpcyk7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3VwZGF0ZU1vZHVsZShvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZSwKCSAqICAgICAgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLnJlc291cmNlcy5JTW9kdWxlUmVzb3VyY2VEZWx0YSkKCSAqLwoJcHVibGljIHZvaWQgdXBkYXRlTW9kdWxlKElNb2R1bGUgbW9kdWxlLCBJTW9kdWxlUmVzb3VyY2VEZWx0YSBkZWx0YSkgewoJCS8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJDb25maWd1cmF0aW9uIHVwZGF0ZWQgIiArIHRoaXMpOwoJCS8vc2V0Q29uZmlndXJhdGlvblN5bmNTdGF0ZShTWU5DX1NUQVRFX0RJUlRZKTsKCQkvL3NldFJlc3RhcnROZWVkZWQodHJ1ZSk7CgoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNwdWJsaXNoU3RhcnQob3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3IpCgkgKi8KCXB1YmxpYyBJU3RhdHVzIHB1Ymxpc2hTdGFydChJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgIlB1Ymxpc2hpbmdTdGFydGVkIiwgbnVsbCk7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3B1Ymxpc2hDb25maWd1cmF0aW9uKG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgSVN0YXR1cyBwdWJsaXNoQ29uZmlndXJhdGlvbihJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCgkJcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5PSywgQ29yZVBsdWdpbi5QTFVHSU5fSUQsIDAsICJQdWJsaXNoZWQgQ29uZmlndXJhdGlvbiIsIG51bGwpOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNwdWJsaXNoU3RvcChvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIElTdGF0dXMgcHVibGlzaFN0b3AoSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJZkxpdmVTZXJ2ZXIuc2V0Q29uZmlndXJhdGlvblN5bmNTdGF0ZShJU2VydmVyLlNZTkNfU1RBVEVfSU5fU1lOQyk7CgkJcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5PSywgQ29yZVBsdWdpbi5QTFVHSU5fSUQsIDAsICJQdWJsaXNoZWQgQ29uZmlndXJhdGlvbiIsIG51bGwpOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNjYW5Nb2RpZnlNb2R1bGVzKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlW10sCgkgKiAgICAgIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlW10pCgkgKi8KCXB1YmxpYyBJU3RhdHVzIGNhbk1vZGlmeU1vZHVsZXMoSU1vZHVsZVtdIGFkZCwgSU1vZHVsZVtdIHJlbW92ZSkgewoJCS8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgIkNhbk1vZGlmeU1vZHVsZXMiLCBudWxsKTsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjZ2V0TW9kdWxlcygpCgkgKi8KCXB1YmxpYyBJTW9kdWxlW10gZ2V0TW9kdWxlcygpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJTGlzdCBsaXN0ID0gIEoyZWVTcGVjTW9kdWxlRmFjdG9yeURlbGVnYXRlLmdldEluc3RhbmNlKCkuZ2V0TW9kdWxlcygpOwoJCXJldHVybiAoSU1vZHVsZVtdKWxpc3QudG9BcnJheShuZXcgSU1vZHVsZVtsaXN0LnNpemUoKV0pOwoJfQoKCQoJcHJvdGVjdGVkIElXZWJNb2R1bGUgZ2V0V2ViTW9kdWxlKElQcm9qZWN0IHByb2plY3QpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQoJCXJldHVybiBudWxsOwoJfQoKCgkJCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjZ2V0TW9kdWxlU3RhdGUob3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGUpCgkgKi8KCXB1YmxpYyBieXRlIGdldE1vZHVsZVN0YXRlKElNb2R1bGUgbW9kdWxlKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCXJldHVybiBJU2VydmVyLk1PRFVMRV9TVEFURV9TVEFSVEVEOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNnZXRSZXBhaXJDb21tYW5kcyhvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZUZhY3RvcnlFdmVudFtdLAoJICogICAgICBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZUV2ZW50W10pCgkgKi8KCXB1YmxpYyBJVGFza1tdIGdldFJlcGFpckNvbW1hbmRzKElNb2R1bGVGYWN0b3J5RXZlbnRbXSBmYWN0b3J5RXZlbnQsCgkJCUlNb2R1bGVFdmVudFtdIG1vZHVsZUV2ZW50KSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCXJldHVybiBudWxsOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNnZXRDaGlsZE1vZHVsZXMob3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGUpCgkgKi8KCXB1YmxpYyBMaXN0IGdldENoaWxkTW9kdWxlcyhJTW9kdWxlIG1vZHVsZSkgewoJCS8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKCQlyZXR1cm4gbnVsbDsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjZ2V0UGFyZW50TW9kdWxlcyhvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZSkKCSAqLwoJcHVibGljIExpc3QgZ2V0UGFyZW50TW9kdWxlcyhJTW9kdWxlIG1vZHVsZSkgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCQkvL0ZJWE1FIFRoaXMgaXMgdmFsaWQgZm9yIG9ubHkgd2ViIG1vZHVsZXMuIEEgZ2VuZXJpYyBzZXJ2ZXIgc2hvdWxkIHN1cHBvcnQgYW55IAoJCQkvLyBraW5kIG9mIGoyZWUgbW9kdWxlLiBGaXggdGhpcyBhZnRlciB0aGUgc2VydmVyIGFyY2hpdGVjdHVyZXMgYXJlIGRldGVybWluZWQuCgkJaWYgKG1vZHVsZSBpbnN0YW5jZW9mIElXZWJNb2R1bGUpIHsKCQkJSVdlYk1vZHVsZSB3ZWJNb2R1bGUgPSAoSVdlYk1vZHVsZSkgbW9kdWxlOwoJCQlJU3RhdHVzIHN0YXR1cyA9IGNhbk1vZGlmeU1vZHVsZXMobmV3IElNb2R1bGVbXSB7IG1vZHVsZSB9LCBudWxsKTsKCQkJaWYgKHN0YXR1cyA9PSBudWxsIHx8ICFzdGF0dXMuaXNPSygpKQoJCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oc3RhdHVzKTsKCQkJQXJyYXlMaXN0IGwgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCWwuYWRkKHdlYk1vZHVsZSk7CgkJCXJldHVybiBsOwoJCX0gZWxzZQoJCQlyZXR1cm4gbnVsbDsKCQoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNzZXRMYXVuY2hEZWZhdWx0cyhvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLklMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkpCgkgKi8KCXB1YmxpYyB2b2lkIHNldExhdW5jaERlZmF1bHRzKElMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd29ya2luZ0NvcHkpIHsKCQlmTGl2ZVNlcnZlci5nZXRSdW50aW1lKCkuZ2V0RGVsZWdhdGUoKTsKCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9NQUlOX1RZUEVfTkFNRSwKCQkJCWdldFN0YXJ0Q2xhc3NOYW1lKCkpOwoKCQlHZW5lcmljU2VydmVyUnVudGltZSBydW50aW1lID0gKEdlbmVyaWNTZXJ2ZXJSdW50aW1lKSBmTGl2ZVNlcnZlcgoJCQkJLmdldFJ1bnRpbWUoKS5nZXREZWxlZ2F0ZSgpOwoKCQlJVk1JbnN0YWxsIHZtSW5zdGFsbCA9IHJ1bnRpbWUuZ2V0Vk1JbnN0YWxsKCk7CgkJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKAoJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fSU5TVEFMTF9UWVBFLCBydW50aW1lCgkJCQkJCS5nZXRWTUluc3RhbGxUeXBlSWQoKSk7CgkJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKAoJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fSU5TVEFMTF9OQU1FLAoJCQkJdm1JbnN0YWxsLmdldE5hbWUoKSk7CgoJCXNldHVwTGF1bmNoQ2xhc3NwYXRoKHdvcmtpbmdDb3B5LCB2bUluc3RhbGwpOwoKCgkJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKAoJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfV09SS0lOR19ESVJFQ1RPUlksCgkJCQlnZXRXb3JraW5nRGlyZWN0b3J5KCkpOwoJCXdvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZSgKCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1BST0dSQU1fQVJHVU1FTlRTLAoJCQkJZ2V0UHJvZ3JhbUFyZ3VtZW50cygpKTsKCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9BUkdVTUVOVFMsCgkJCQlnZXRWbUFyZ3VtZW50cygpKTsKCgkJLy93b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fSU5TVEFMTF9UWVBFX1NQRUNJRklDX0FUVFJTX01BUCwpOwoKCX0KCglwcml2YXRlIExpc3QgZ2V0Q2xhc3NwYXRoTWVtZW50b3MoKSB7CgkJTGlzdCBjcGF0aExpc3QgPSBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U2VydmVyQ2xhc3NQYXRoKCk7CgkJQXJyYXlMaXN0IG1lbWVudG9MaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgY3BhdGhMaXN0LnNpemUoKTsgaSsrKSB7CgkJCUNsYXNzcGF0aEl0ZW0gaXRlbSA9IChDbGFzc3BhdGhJdGVtKSBjcGF0aExpc3QuZ2V0KGkpOwoJCQlTdHJpbmcgY3BhdGggPSBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkucmVzb2x2ZVByb3BlcnRpZXMoCgkJCQkJaXRlbS5nZXRDbGFzc3BhdGgoKSk7CgkJCVN0cmluZyBtZW1lbnRvID0gbnVsbDsKCQkJdHJ5IHsKCQkJCW1lbWVudG8gPSBKYXZhUnVudGltZS5uZXdBcmNoaXZlUnVudGltZUNsYXNzcGF0aEVudHJ5KAoJCQkJCQluZXcgUGF0aChjcGF0aCkpLmdldE1lbWVudG8oKTsKCQkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNhdGNoIGJsb2NrCgkJCQllLnByaW50U3RhY2tUcmFjZSgpOwoJCQl9CgkJCW1lbWVudG9MaXN0LmFkZChtZW1lbnRvKTsKCQl9CgkJcmV0dXJuIG1lbWVudG9MaXN0OwoJfQoKCXByaXZhdGUgU3RyaW5nIGdldFZtQXJndW1lbnRzKCkgewoJCVN0cmluZyB2bVBhcmFtcyA9IGdldFNlcnZlckRlZmluaXRpb24oKS5yZXNvbHZlUHJvcGVydGllcygKCQkJCWdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTdGFydFZtUGFyYW1ldGVycygpKTsKCQlyZXR1cm4gdm1QYXJhbXM7Cgl9CgoJcHJpdmF0ZSBTdHJpbmcgZ2V0UHJvZ3JhbUFyZ3VtZW50cygpIHsKCQlTdHJpbmcgc3RhcnRQYXJhbXMgPSBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkucmVzb2x2ZVByb3BlcnRpZXMoCgkJCQlnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RhcnRQcm9ncmFtQXJndW1lbnRzKCkpOwoJCXJldHVybiBzdGFydFBhcmFtczsKCX0KCglwcml2YXRlIFN0cmluZyBnZXRXb3JraW5nRGlyZWN0b3J5KCkgewoJCVN0cmluZyB3RGlyZWN0b3J5ID0gZ2V0U2VydmVyRGVmaW5pdGlvbigpLnJlc29sdmVQcm9wZXJ0aWVzKAoJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0YXJ0V29ya2luZ0RpcmVjdG9yeSgpKTsKCQlyZXR1cm4gd0RpcmVjdG9yeTsKCgl9CgoJcHVibGljIFN0cmluZyBnZXRTdGFydENsYXNzTmFtZSgpIHsKCQlyZXR1cm4gZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0YXJ0Q2xhc3MoKTsKCX0KCgkvKioKCSAqIEByZXR1cm4KCSAqLwoJcHJpdmF0ZSBNYXAgZ2V0U2VydmVySW5zdGFuY2VQcm9wZXJ0aWVzKCkgewoJCU1hcCBpbnN0YW5jZVByb3BlcnRpZXMgPSBmTGl2ZVNlcnZlci5nZXRSdW50aW1lKCkuZ2V0QXR0cmlidXRlKAoJCQkJR2VuZXJpY1NlcnZlclJ1bnRpbWUuU0VSVkVSX0lOU1RBTkNFX1BST1BFUlRJRVMsIChNYXApIG51bGwpOwoJCXJldHVybiBpbnN0YW5jZVByb3BlcnRpZXM7Cgl9CgoJcHVibGljIFNlcnZlclR5cGVEZWZpbml0aW9uIGdldFNlcnZlckRlZmluaXRpb24oKSB7CgkJCgkJaWYgKGZTZXJ2ZXJEZWZpbml0aW9uID09IG51bGwpCgkJCWZTZXJ2ZXJEZWZpbml0aW9uID0gQ29yZVBsdWdpbi5nZXREZWZhdWx0KCkKCQkJCQkuZ2V0U2VydmVyVHlwZURlZmluaXRpb25NYW5hZ2VyKCkKCQkJCQkuZ2V0U2VydmVyUnVudGltZURlZmluaXRpb24oCgkJCQkJCQlmTGl2ZVNlcnZlci5nZXRSdW50aW1lKCkuZ2V0QXR0cmlidXRlKAoJCQkJCQkJCQlHZW5lcmljU2VydmVyUnVudGltZS5TRVJWRVJfREVGSU5JVElPTl9JRCwKCQkJCQkJCQkJIiIpLCBnZXRTZXJ2ZXJJbnN0YW5jZVByb3BlcnRpZXMoKSk7CgkJcmV0dXJuIGZTZXJ2ZXJEZWZpbml0aW9uOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb25pdG9yYWJsZVNlcnZlciNnZXRTZXJ2ZXJQb3J0cygpCgkgKi8KCXB1YmxpYyBMaXN0IGdldFNlcnZlclBvcnRzKCkgewoJCUxpc3QgcG9ydHMgPSBuZXcgQXJyYXlMaXN0KCk7CgoJCgkJdHJ5IHsKCQkJaW50IHBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KHRoaXMuZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFBvcnQoKSk7CgkJCXBvcnRzLmFkZChuZXcgU2VydmVyUG9ydCgic2VydmVyIiwgIlNlcnZlciBwb3J0IiwgcG9ydCwgIlRDUElQIikpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJfQoKCQlyZXR1cm4gcG9ydHM7Cgl9CgoJLyogKG5vbi1KYXZhZG9jKQoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVN0YXJ0YWJsZVNlcnZlciNpc1Rlcm1pbmF0ZU9uU2h1dGRvd24oKQoJICovCglwdWJsaWMgYm9vbGVhbiBpc1Rlcm1pbmF0ZU9uU2h1dGRvd24oKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFNldHVwIGZvciBzdGFydGluZyB0aGUgc2VydmVyLgoJICogCgkgKiBAcGFyYW0gbGF1bmNoIElMYXVuY2gKCSAqIEBwYXJhbSBsYXVuY2hNb2RlIFN0cmluZwoJICogQHBhcmFtIG1vbml0b3IgSVByb2dyZXNzTW9uaXRvcgoJICovCglwdWJsaWMgdm9pZCBzZXR1cExhdW5jaChJTGF1bmNoIGxhdW5jaCwgU3RyaW5nIGxhdW5jaE1vZGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWlmICgidHJ1ZSIuZXF1YWxzKGxhdW5jaC5nZXRMYXVuY2hDb25maWd1cmF0aW9uKCkuZ2V0QXR0cmlidXRlKEFUVFJfU1RPUCwgImZhbHNlIikpKQoJCQlyZXR1cm47Ci8vCQlJU3RhdHVzIHN0YXR1cyA9IGdldFJ1bnRpbWUoKS52YWxpZGF0ZSgpOwovLwkJaWYgKHN0YXR1cyAhPSBudWxsICYmICFzdGF0dXMuaXNPSygpKQovLwkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKHN0YXR1cyk7CgoJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSB0aGlzLmdldFNlcnZlclBvcnRzKCkuaXRlcmF0b3IoKTsKCQlJU2VydmVyUG9ydCBzcCA9IG51bGw7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlzcCA9IChJU2VydmVyUG9ydCkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoU29ja2V0VXRpbC5pc1BvcnRJblVzZShzcC5nZXRQb3J0KCksIDUpKQoJCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgIlNlcnZlciBQYXJ0IEluIFVzZSAiK3NwLmdldFBvcnQoKSArICItICIgK3NwLmdldE5hbWUoKSAsbnVsbCkpOwoJCX0KCQkKCQlmTGl2ZVNlcnZlci5zZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNFUlZFUl9TVEFSVElORyk7CgkKCQkvLyBwaW5nIHNlcnZlciB0byBjaGVjayBmb3Igc3RhcnR1cAoJCXRyeSB7CgkJCVN0cmluZyB1cmwgPSAiaHR0cDovL2xvY2FsaG9zdCI7CgkJCWludCBwb3J0ID0gc3AuZ2V0UG9ydCgpOwoJCQlpZiAocG9ydCAhPSA4MCkKCQkJCXVybCArPSAiOiIgKyBwb3J0OwoJCQlwaW5nID0gbmV3IFBpbmdUaHJlYWQodGhpcywgZkxpdmVTZXJ2ZXIsIHVybCwgbGF1bmNoTW9kZSk7CgkJCXBpbmcuc3RhcnQoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDYW4ndCBwaW5nIGZvciBzZXJ2ZXIgc3RhcnR1cC4iKTsKCQl9Cgl9CgkKCS8qKgoJICogQ2xlYW5seSBzaHV0cyBkb3duIGFuZCB0ZXJtaW5hdGVzIHRoZSBzZXJ2ZXIuCgkgKi8KCXB1YmxpYyB2b2lkIHN0b3AoKSB7CgkJYnl0ZSBzdGF0ZSA9IHRoaXMuZkxpdmVTZXJ2ZXIuZ2V0U2VydmVyU3RhdGUoKTsKCQlpZiAoc3RhdGUgPT0gSVNlcnZlci5TRVJWRVJfU1RPUFBFRCkKCQkJcmV0dXJuOwoJCWVsc2UgaWYgKHN0YXRlID09IElTZXJ2ZXIuU0VSVkVSX1NUQVJUSU5HIHx8IHN0YXRlID09IElTZXJ2ZXIuU0VSVkVSX1NUT1BQSU5HKSB7CgkJCXRlcm1pbmF0ZSgpOwoJCQlyZXR1cm47CgkJfQoKCQl0cnkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJTdG9wcGluZyBTZXJ2ZXIiKTsKCQkJaWYgKHN0YXRlICE9IElTZXJ2ZXIuU0VSVkVSX1NUT1BQRUQpCgkJCQlmTGl2ZVNlcnZlci5zZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNFUlZFUl9TVE9QUElORyk7CgkJCUlMYXVuY2hNYW5hZ2VyIG1nciA9IERlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5nZXRMYXVuY2hNYW5hZ2VyKCk7CgoJCQlJTGF1bmNoQ29uZmlndXJhdGlvblR5cGUgdHlwZSA9CgkJCQltZ3IuZ2V0TGF1bmNoQ29uZmlndXJhdGlvblR5cGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLklEX0pBVkFfQVBQTElDQVRJT04pOwoKCQkJU3RyaW5nIGxhdW5jaE5hbWUgPSAiR2VuZXJpY1NlcnZlclN0b3BwZXIiOwoJCQlTdHJpbmcgdW5pcXVlTGF1bmNoTmFtZSA9CgkJCQltZ3IuZ2VuZXJhdGVVbmlxdWVMYXVuY2hDb25maWd1cmF0aW9uTmFtZUZyb20obGF1bmNoTmFtZSk7CgkJCUlMYXVuY2hDb25maWd1cmF0aW9uIGNvbmYgPSBudWxsOwoKCQkJSUxhdW5jaENvbmZpZ3VyYXRpb25bXSBsY2ggPSBtZ3IuZ2V0TGF1bmNoQ29uZmlndXJhdGlvbnModHlwZSk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGNoLmxlbmd0aDsgaSsrKSB7CgkJCQlpZiAobGF1bmNoTmFtZS5lcXVhbHMobGNoW2ldLmdldE5hbWUoKSkpIHsKCQkJCQljb25mID0gbGNoW2ldOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgoJCQlJTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5IHdjID0gbnVsbDsKCQkJaWYgKGNvbmYgIT0gbnVsbCkgewoJCQkJd2MgPSBjb25mLmdldFdvcmtpbmdDb3B5KCk7CgkJCX0gZWxzZSB7CgkJCQl3YyA9IHR5cGUubmV3SW5zdGFuY2UobnVsbCwgdW5pcXVlTGF1bmNoTmFtZSk7CgkJCX0KCQkJLy9UbyBzdG9wIGZyb20gYXBwZWFyaW5nIGluIGhpc3RvcnkgbGlzdHMKCQkJd2Muc2V0QXR0cmlidXRlKElEZWJ1Z1VJQ29uc3RhbnRzLkFUVFJfUFJJVkFURSwgdHJ1ZSk7CQkJCgkKCQkJd2Muc2V0QXR0cmlidXRlKAoJCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX01BSU5fVFlQRV9OQU1FLAoJCQkJCXRoaXMuZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3BDbGFzcygpKTsKCgkJCUdlbmVyaWNTZXJ2ZXJSdW50aW1lIHJ1bnRpbWUgPSAoR2VuZXJpY1NlcnZlclJ1bnRpbWUpIGZMaXZlU2VydmVyCgkJCQkJLmdldFJ1bnRpbWUoKS5nZXREZWxlZ2F0ZSgpOwoKCQkJSVZNSW5zdGFsbCB2bUluc3RhbGwgPSBydW50aW1lLmdldFZNSW5zdGFsbCgpOwoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fSU5TVEFMTF9UWVBFLCBydW50aW1lCgkJCQkJCQkuZ2V0Vk1JbnN0YWxsVHlwZUlkKCkpOwoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fSU5TVEFMTF9OQU1FLAoJCQkJCXZtSW5zdGFsbC5nZXROYW1lKCkpOwoKCQkJc2V0dXBMYXVuY2hDbGFzc3BhdGgod2MsIHZtSW5zdGFsbCk7CgoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfV09SS0lOR19ESVJFQ1RPUlksCgkJCQkJZ2V0V29ya2luZ0RpcmVjdG9yeSgpKTsKCQkJd2Muc2V0QXR0cmlidXRlKAoJCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1BST0dSQU1fQVJHVU1FTlRTLAoJCQkJCWdldFNlcnZlckRlZmluaXRpb24oKS5yZXNvbHZlUHJvcGVydGllcygKCQkJCQkJCWdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTdG9wUHJvZ3JhbUFyZ3VtZW50cygpKSk7CgkJCXdjLnNldEF0dHJpYnV0ZSgKCQkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9BUkdVTUVOVFMsCgkJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLnJlc29sdmVQcm9wZXJ0aWVzKAoJCQkJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3BWbVBhcmFtZXRlcnMoKSkpOwkJCQkKCQkJd2Muc2V0QXR0cmlidXRlKEFUVFJfU1RPUCwgInRydWUiKTsKCQkJd2MubGF1bmNoKElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFLCBuZXcgTnVsbFByb2dyZXNzTW9uaXRvcigpKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBzdG9wcGluZyBTZXJ2ZXIiLCBlKTsKCQl9Cgl9CgoKCS8qKgoJICogQHBhcmFtIHdjCgkgKiBAcGFyYW0gdm1JbnN0YWxsCgkgKi8KCXByaXZhdGUgdm9pZCBzZXR1cExhdW5jaENsYXNzcGF0aChJTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5IHdjLCBJVk1JbnN0YWxsIHZtSW5zdGFsbCkgewoJCUxpc3QgY3AgPSBnZXRDbGFzc3BhdGhNZW1lbnRvcygpOwoKCQkvLyBhZGQgdG9vbHMuamFyIHRvIHRoZSBwYXRoCgkJaWYgKHZtSW5zdGFsbCAhPSBudWxsKSB7CgkJCXRyeSB7CgkJCQljcAoJCQkJCQkuYWRkKEphdmFSdW50aW1lCgkJCQkJCQkJLm5ld1J1bnRpbWVDb250YWluZXJDbGFzc3BhdGhFbnRyeSgKCQkJCQkJCQkJCW5ldyBQYXRoKEphdmFSdW50aW1lLkpSRV9DT05UQUlORVIpCgkJCQkJCQkJCQkJCS5hcHBlbmQoCgkJCQkJCQkJCQkJCQkJIm9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC5kZWJ1Zy51aS5sYXVuY2hlci5TdGFuZGFyZFZNVHlwZSIpCgkJCQkJCQkJCQkJCS5hcHBlbmQodm1JbnN0YWxsLmdldE5hbWUoKSksCgkJCQkJCQkJCQlJUnVudGltZUNsYXNzcGF0aEVudHJ5LkJPT1RTVFJBUF9DTEFTU0VTKQoJCQkJCQkJCS5nZXRNZW1lbnRvKCkpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQl9CgoJCQlJUGF0aCBqcmVQYXRoID0gbmV3IFBhdGgodm1JbnN0YWxsLmdldEluc3RhbGxMb2NhdGlvbigpCgkJCQkJLmdldEFic29sdXRlUGF0aCgpKTsKCQkJaWYgKGpyZVBhdGggIT0gbnVsbCkgewoJCQkJSVBhdGggdG9vbHNQYXRoID0ganJlUGF0aC5hcHBlbmQoImxpYiIpLmFwcGVuZCgidG9vbHMuamFyIik7CgkJCQlpZiAodG9vbHNQYXRoLnRvRmlsZSgpLmV4aXN0cygpKSB7CgkJCQkJdHJ5IHsKCQkJCQkJY3AuYWRkKEphdmFSdW50aW1lLm5ld0FyY2hpdmVSdW50aW1lQ2xhc3NwYXRoRW50cnkoCgkJCQkJCQkJdG9vbHNQYXRoKS5nZXRNZW1lbnRvKCkpOwoJCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZTEpIHsKCQkJCQkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBjYXRjaCBibG9jawoJCQkJCQllMS5wcmludFN0YWNrVHJhY2UoKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCXdjLnNldEF0dHJpYnV0ZSgKCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX0NMQVNTUEFUSCwgY3ApOwoJCXdjLnNldEF0dHJpYnV0ZSgKCQkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfREVGQVVMVF9DTEFTU1BBVEgsCgkJCQkJCWZhbHNlKTsKCX0KCgkvKioKCSAqIFRlcm1pbmF0ZXMgdGhlIHNlcnZlci4KCSAqLwoJcHVibGljIHZvaWQgdGVybWluYXRlKCkgewoJCWlmIChmTGl2ZVNlcnZlci5nZXRTZXJ2ZXJTdGF0ZSgpID09IElTZXJ2ZXIuU0VSVkVSX1NUT1BQRUQpCgkJCXJldHVybjsKCgkJdHJ5IHsKCQkJZkxpdmVTZXJ2ZXIuc2V0U2VydmVyU3RhdGUoSVNlcnZlci5TRVJWRVJfU1RPUFBJTkcpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJLaWxsaW5nIHRoZSBTZXJ2ZXIgcHJvY2VzcyIpOwoJCQlpZiAocHJvY2VzcyAhPSBudWxsICYmICFwcm9jZXNzLmlzVGVybWluYXRlZCgpKSB7CgkJCQlwcm9jZXNzLnRlcm1pbmF0ZSgpOwoJCQkJc3RvcEltcGwoKTsKCQkJfQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGtpbGxpbmcgdGhlIHByb2Nlc3MiLCBlKTsKCQl9Cgl9CgkKCXByb3RlY3RlZCB2b2lkIHN0b3BJbXBsKCkgewoJCWlmIChwaW5nICE9IG51bGwpIHsKCQkJcGluZy5zdG9wUGluZ2luZygpOwoJCQlwaW5nID0gbnVsbDsKCQl9CgkJaWYgKHByb2Nlc3MgIT0gbnVsbCkgewoJCQlwcm9jZXNzID0gbnVsbDsKCQkJRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLnJlbW92ZURlYnVnRXZlbnRMaXN0ZW5lcihwcm9jZXNzTGlzdGVuZXIpOwoJCQlwcm9jZXNzTGlzdGVuZXIgPSBudWxsOwoJCX0KCQlmTGl2ZVNlcnZlci5zZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNFUlZFUl9TVE9QUEVEKTsKCX0JCglwdWJsaWMgdm9pZCBzZXRQcm9jZXNzKGZpbmFsIElQcm9jZXNzIG5ld1Byb2Nlc3MpIHsKCQlpZiAocHJvY2VzcyAhPSBudWxsKQoJCQlyZXR1cm47CgoJCXByb2Nlc3MgPSBuZXdQcm9jZXNzOwoJCXByb2Nlc3NMaXN0ZW5lciA9IG5ldyBJRGVidWdFdmVudFNldExpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBoYW5kbGVEZWJ1Z0V2ZW50cyhEZWJ1Z0V2ZW50W10gZXZlbnRzKSB7CgkJCQlpZiAoZXZlbnRzICE9IG51bGwpIHsKCQkJCQlpbnQgc2l6ZSA9IGV2ZW50cy5sZW5ndGg7CgkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQkJaWYgKHByb2Nlc3MuZXF1YWxzKGV2ZW50c1tpXS5nZXRTb3VyY2UoKSkgJiYgZXZlbnRzW2ldLmdldEtpbmQoKSA9PSBEZWJ1Z0V2ZW50LlRFUk1JTkFURSkgewoJCQkJCQkJRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLnJlbW92ZURlYnVnRXZlbnRMaXN0ZW5lcih0aGlzKTsKCQkJCQkJCXN0b3BJbXBsKCk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9OwoJCURlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5hZGREZWJ1Z0V2ZW50TGlzdGVuZXIocHJvY2Vzc0xpc3RlbmVyKTsKCX0KCQoJcHVibGljIGludCBnZXRTdGFydFRpbWVvdXQoKSB7CgkJcmV0dXJuIDMwMDAwMDsKCX0KCQoJcHVibGljIGludCBnZXRTdG9wVGltZW91dCgpIHsKCQlyZXR1cm4gMzAwMDAwOwoJfQoJLyogKG5vbi1KYXZhZG9jKQoJICogQHNlZSBvcmcuZWNsaXBzZS53dHAuc2VydmVyLmNvcmUubW9kZWwuSVVSTFByb3ZpZGVyI2dldE1vZHVsZVJvb3RVUkwob3JnLmVjbGlwc2Uud3RwLnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGUpCgkgKi8KCXB1YmxpYyBVUkwgZ2V0TW9kdWxlUm9vdFVSTChJTW9kdWxlIG1vZHVsZSkgewoKCQl0cnkgewoJCQlpZiAobW9kdWxlID09IG51bGwgfHwgIShtb2R1bGUgaW5zdGFuY2VvZiBJV2ViTW9kdWxlKSkKCQkJCXJldHVybiBudWxsOwoKCQkJSVNlcnZlckNvbmZpZ3VyYXRpb24gc2VydmVyQ29uZmlnID0gZkxpdmVTZXJ2ZXIKCQkJCQkuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpOwoJCQlpZiAoc2VydmVyQ29uZmlnID09IG51bGwpCgkJCQlyZXR1cm4gbnVsbDsKCgkJCVN0cmluZyB1cmwgPSAiaHR0cDovL2xvY2FsaG9zdCI7CgkJCWludCBwb3J0ID0gSW50ZWdlci5wYXJzZUludChnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0UG9ydCgpKTsKCQkJcG9ydCA9IFNlcnZlckNvcmUuZ2V0U2VydmVyTW9uaXRvck1hbmFnZXIoKS5nZXRNb25pdG9yZWRQb3J0KAoJCQkJCWZMaXZlU2VydmVyLCBwb3J0LCAid2ViIik7CgkJCWlmIChwb3J0ICE9IDgwKQoJCQkJdXJsICs9ICI6IiArIHBvcnQ7CgoJCQl1cmwgKz0gIi8iK21vZHVsZS5nZXROYW1lKCk7CgoJCQlpZiAoIXVybC5lbmRzV2l0aCgiLyIpKQoJCQkJdXJsICs9ICIvIjsKCgkJCXJldHVybiBuZXcgVVJMKHVybCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoIkNvdWxkIG5vdCBnZXQgcm9vdCBVUkwiLCBlKTsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCX0KCn0=