LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBHb3JrZW0gRXJjYW4gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE5hY2kgTS4gRGFpCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBFVEVSQVRJT04gQS5TLiBPUgogKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgogKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAogKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQogKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4gIEZvciBtb3JlCiAqIGluZm9ybWF0aW9uIG9uIGV0ZXJhdGlvbiwgcGxlYXNlIHNlZQogKiA8aHR0cDovL3d3dy5ldGVyYXRpb24uY29tLz4uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmludGVybmFsLmNvcmU7CgppbXBvcnQgamF2YS5uZXQuVVJMOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLk51bGxQcm9ncmVzc01vbml0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5TdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLkRlYnVnRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLkRlYnVnUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JRGVidWdFdmVudFNldExpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoQ29uZmlndXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25UeXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5OwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoTWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUubW9kZWwuSVByb2Nlc3M7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy51aS5JRGVidWdVSUNvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JUnVudGltZUNsYXNzcGF0aEVudHJ5OwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JVk1JbnN0YWxsOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5KYXZhUnVudGltZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuZ2VuZXJpYy5jb3JlLkNvcmVQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuaW50ZXJuYWwueG1sLkNsYXNzcGF0aEl0ZW07CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuaW50ZXJuYWwueG1sLlNlcnZlclR5cGVEZWZpbml0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLm1vZHVsZXMuSjJlZVNwZWNNb2R1bGVGYWN0b3J5RGVsZWdhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmoyZWUuSVdlYk1vZHVsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJDb25maWd1cmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJTdGF0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JVGFzazsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5TZXJ2ZXJDb3JlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZUV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGVGYWN0b3J5RXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vbml0b3JhYmxlU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklQdWJsaXNoZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJQb3J0OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTdGFydGFibGVTZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVVSTFByb3ZpZGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLnJlc291cmNlcy5JTW9kdWxlUmVzb3VyY2VEZWx0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS51dGlsLlNlcnZlclBvcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUudXRpbC5Tb2NrZXRVdGlsOwoKLyoqCiAqIEdlbmVyaWMgWE1MIGJhc2VkIHNlcnZlciBpbXBsZW1lbnRhdGlvbi4KICogCiAqIEBhdXRob3IgR29ya2VtIEVyY2FuCiAqLwpwdWJsaWMgY2xhc3MgR2VuZXJpY1NlcnZlciBpbXBsZW1lbnRzIElTZXJ2ZXJEZWxlZ2F0ZSwgSVN0YXJ0YWJsZVNlcnZlciwgSU1vbml0b3JhYmxlU2VydmVyLElVUkxQcm92aWRlciB7Cglwcml2YXRlIElTZXJ2ZXJTdGF0ZSBmTGl2ZVNlcnZlcjsKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX1NUT1AgPSAic3RvcC1zZXJ2ZXIiOwoJCgkvLyB0aGUgdGhyZWFkIHVzZWQgdG8gcGluZyB0aGUgc2VydmVyIHRvIGNoZWNrIGZvciBzdGFydHVwCglwcm90ZWN0ZWQgdHJhbnNpZW50IFBpbmdUaHJlYWQgcGluZyA9IG51bGw7Cglwcm90ZWN0ZWQgdHJhbnNpZW50IElQcm9jZXNzIHByb2Nlc3M7Cglwcm90ZWN0ZWQgdHJhbnNpZW50IElEZWJ1Z0V2ZW50U2V0TGlzdGVuZXIgcHJvY2Vzc0xpc3RlbmVyOwoJCglwcml2YXRlIFNlcnZlclR5cGVEZWZpbml0aW9uIGZTZXJ2ZXJEZWZpbml0aW9uOwoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNpbml0aWFsaXplKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyU3RhdGUpCgkgKi8KCXB1YmxpYyB2b2lkIGluaXRpYWxpemUoSVNlcnZlclN0YXRlIGxpdmVTZXJ2ZXIpIHsKCQl0aGlzLmZMaXZlU2VydmVyID0gbGl2ZVNlcnZlcjsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjZGlzcG9zZSgpCgkgKi8KCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJdGhpcy5mTGl2ZVNlcnZlciA9IG51bGw7CgoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcHJvamVjdCBwdWJsaXNoZXIgdGhhdCBjYW4gYmUgdXNlZCB0bwoJICogcHVibGlzaCB0aGUgZ2l2ZW4gcHJvamVjdC4KCSAqCgkgKiBAcGFyYW0gcHJvamVjdCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUHJvamVjdAoJICogQHJldHVybiBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVByb2plY3RQdWJsaXNoZXIKCSAqLwoJcHVibGljIElQdWJsaXNoZXIgZ2V0UHVibGlzaGVyKExpc3QgcGFyZW50cywgSU1vZHVsZSBtb2R1bGUpIHsKCQlyZXR1cm4gbmV3IEFudFB1Ymxpc2hlcihwYXJlbnRzLCBtb2R1bGUsIHRoaXMuZ2V0U2VydmVyRGVmaW5pdGlvbigpKTsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjdXBkYXRlQ29uZmlndXJhdGlvbigpCgkgKi8KCXB1YmxpYyB2b2lkIHVwZGF0ZUNvbmZpZ3VyYXRpb24oKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAidXBkYXRlQ29uZmlndXJhdGlvbiIgKyB0aGlzKTsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjdXBkYXRlTW9kdWxlKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlLAoJICogICAgICBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUucmVzb3VyY2VzLklNb2R1bGVSZXNvdXJjZURlbHRhKQoJICovCglwdWJsaWMgdm9pZCB1cGRhdGVNb2R1bGUoSU1vZHVsZSBtb2R1bGUsIElNb2R1bGVSZXNvdXJjZURlbHRhIGRlbHRhKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIkNvbmZpZ3VyYXRpb24gdXBkYXRlZCAiICsgdGhpcyk7CgkJLy9zZXRDb25maWd1cmF0aW9uU3luY1N0YXRlKFNZTkNfU1RBVEVfRElSVFkpOwoJCS8vc2V0UmVzdGFydE5lZWRlZCh0cnVlKTsKCgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3B1Ymxpc2hTdGFydChvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIElTdGF0dXMgcHVibGlzaFN0YXJ0KElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIENvcmVQbHVnaW4uUExVR0lOX0lELCAwLCAiUHVibGlzaGluZ1N0YXJ0ZWQiLCBudWxsKTsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjcHVibGlzaENvbmZpZ3VyYXRpb24ob3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3IpCgkgKi8KCXB1YmxpYyBJU3RhdHVzIHB1Ymxpc2hDb25maWd1cmF0aW9uKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoKCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgIlB1Ymxpc2hlZCBDb25maWd1cmF0aW9uIiwgbnVsbCk7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3B1Ymxpc2hTdG9wKG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgSVN0YXR1cyBwdWJsaXNoU3RvcChJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlmTGl2ZVNlcnZlci5zZXRDb25maWd1cmF0aW9uU3luY1N0YXRlKElTZXJ2ZXIuU1lOQ19TVEFURV9JTl9TWU5DKTsKCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgIlB1Ymxpc2hlZCBDb25maWd1cmF0aW9uIiwgbnVsbCk7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI2Nhbk1vZGlmeU1vZHVsZXMob3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGVbXSwKCSAqICAgICAgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGVbXSkKCSAqLwoJcHVibGljIElTdGF0dXMgY2FuTW9kaWZ5TW9kdWxlcyhJTW9kdWxlW10gYWRkLCBJTW9kdWxlW10gcmVtb3ZlKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIENvcmVQbHVnaW4uUExVR0lOX0lELCAwLCAiQ2FuTW9kaWZ5TW9kdWxlcyIsIG51bGwpOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNnZXRNb2R1bGVzKCkKCSAqLwoJcHVibGljIElNb2R1bGVbXSBnZXRNb2R1bGVzKCkgewoJCS8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKCQlMaXN0IGxpc3QgPSAgSjJlZVNwZWNNb2R1bGVGYWN0b3J5RGVsZWdhdGUuZ2V0SW5zdGFuY2UoKS5nZXRNb2R1bGVzKCk7CgkJcmV0dXJuIChJTW9kdWxlW10pbGlzdC50b0FycmF5KG5ldyBJTW9kdWxlW2xpc3Quc2l6ZSgpXSk7Cgl9CgoJCglwcm90ZWN0ZWQgSVdlYk1vZHVsZSBnZXRXZWJNb2R1bGUoSVByb2plY3QgcHJvamVjdCkgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCgkJcmV0dXJuIG51bGw7Cgl9CgoKCQkKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNnZXRNb2R1bGVTdGF0ZShvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZSkKCSAqLwoJcHVibGljIGJ5dGUgZ2V0TW9kdWxlU3RhdGUoSU1vZHVsZSBtb2R1bGUpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJcmV0dXJuIElTZXJ2ZXIuTU9EVUxFX1NUQVRFX1NUQVJURUQ7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI2dldFJlcGFpckNvbW1hbmRzKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlRmFjdG9yeUV2ZW50W10sCgkgKiAgICAgIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlRXZlbnRbXSkKCSAqLwoJcHVibGljIElUYXNrW10gZ2V0UmVwYWlyQ29tbWFuZHMoSU1vZHVsZUZhY3RvcnlFdmVudFtdIGZhY3RvcnlFdmVudCwKCQkJSU1vZHVsZUV2ZW50W10gbW9kdWxlRXZlbnQpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI2dldENoaWxkTW9kdWxlcyhvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZSkKCSAqLwoJcHVibGljIExpc3QgZ2V0Q2hpbGRNb2R1bGVzKElNb2R1bGUgbW9kdWxlKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCXJldHVybiBudWxsOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNnZXRQYXJlbnRNb2R1bGVzKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlKQoJICovCglwdWJsaWMgTGlzdCBnZXRQYXJlbnRNb2R1bGVzKElNb2R1bGUgbW9kdWxlKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJCS8vRklYTUUgVGhpcyBpcyB2YWxpZCBmb3Igb25seSB3ZWIgbW9kdWxlcy4gQSBnZW5lcmljIHNlcnZlciBzaG91bGQgc3VwcG9ydCBhbnkgCgkJCS8vIGtpbmQgb2YgajJlZSBtb2R1bGUuIEZpeCB0aGlzIGFmdGVyIHRoZSBzZXJ2ZXIgYXJjaGl0ZWN0dXJlcyBhcmUgZGV0ZXJtaW5lZC4KCQlpZiAobW9kdWxlIGluc3RhbmNlb2YgSVdlYk1vZHVsZSkgewoJCQlJV2ViTW9kdWxlIHdlYk1vZHVsZSA9IChJV2ViTW9kdWxlKSBtb2R1bGU7CgkJCUlTdGF0dXMgc3RhdHVzID0gY2FuTW9kaWZ5TW9kdWxlcyhuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sIG51bGwpOwoJCQlpZiAoc3RhdHVzID09IG51bGwgfHwgIXN0YXR1cy5pc09LKCkpCgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwoJCQlBcnJheUxpc3QgbCA9IG5ldyBBcnJheUxpc3QoKTsKCQkJbC5hZGQod2ViTW9kdWxlKTsKCQkJcmV0dXJuIGw7CgkJfSBlbHNlCgkJCXJldHVybiBudWxsOwoJCgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3NldExhdW5jaERlZmF1bHRzKG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSkKCSAqLwoJcHVibGljIHZvaWQgc2V0TGF1bmNoRGVmYXVsdHMoSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSB3b3JraW5nQ29weSkgewoJCWZMaXZlU2VydmVyLmdldFJ1bnRpbWUoKS5nZXREZWxlZ2F0ZSgpOwoJCXdvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZSgKCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX01BSU5fVFlQRV9OQU1FLAoJCQkJZ2V0U3RhcnRDbGFzc05hbWUoKSk7CgoJCUdlbmVyaWNTZXJ2ZXJSdW50aW1lIHJ1bnRpbWUgPSAoR2VuZXJpY1NlcnZlclJ1bnRpbWUpIGZMaXZlU2VydmVyCgkJCQkuZ2V0UnVudGltZSgpLmdldERlbGVnYXRlKCk7CgoJCUlWTUluc3RhbGwgdm1JbnN0YWxsID0gcnVudGltZS5nZXRWTUluc3RhbGwoKTsKCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX1RZUEUsIHJ1bnRpbWUKCQkJCQkJLmdldFZNSW5zdGFsbFR5cGVJZCgpKTsKCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX05BTUUsCgkJCQl2bUluc3RhbGwuZ2V0TmFtZSgpKTsKCgkJc2V0dXBMYXVuY2hDbGFzc3BhdGgod29ya2luZ0NvcHksIHZtSW5zdGFsbCk7CgoKCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9XT1JLSU5HX0RJUkVDVE9SWSwKCQkJCWdldFdvcmtpbmdEaXJlY3RvcnkoKSk7CgkJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKAoJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfUFJPR1JBTV9BUkdVTUVOVFMsCgkJCQlnZXRQcm9ncmFtQXJndW1lbnRzKCkpOwoJCXdvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZSgKCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1ZNX0FSR1VNRU5UUywKCQkJCWdldFZtQXJndW1lbnRzKCkpOwoKCQkvL3dvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZShJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX1RZUEVfU1BFQ0lGSUNfQVRUUlNfTUFQLCk7CgoJfQoKCXByaXZhdGUgTGlzdCBnZXRDbGFzc3BhdGhNZW1lbnRvcygpIHsKCQlMaXN0IGNwYXRoTGlzdCA9IGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTZXJ2ZXJDbGFzc1BhdGgoKTsKCQlBcnJheUxpc3QgbWVtZW50b0xpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBjcGF0aExpc3Quc2l6ZSgpOyBpKyspIHsKCQkJQ2xhc3NwYXRoSXRlbSBpdGVtID0gKENsYXNzcGF0aEl0ZW0pIGNwYXRoTGlzdC5nZXQoaSk7CgkJCVN0cmluZyBjcGF0aCA9IGdldFNlcnZlckRlZmluaXRpb24oKS5yZXNvbHZlUHJvcGVydGllcygKCQkJCQlpdGVtLmdldENsYXNzcGF0aCgpKTsKCQkJU3RyaW5nIG1lbWVudG8gPSBudWxsOwoJCQl0cnkgewoJCQkJbWVtZW50byA9IEphdmFSdW50aW1lLm5ld0FyY2hpdmVSdW50aW1lQ2xhc3NwYXRoRW50cnkoCgkJCQkJCW5ldyBQYXRoKGNwYXRoKSkuZ2V0TWVtZW50bygpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJCS8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY2F0Y2ggYmxvY2sKCQkJCWUucHJpbnRTdGFja1RyYWNlKCk7CgkJCX0KCQkJbWVtZW50b0xpc3QuYWRkKG1lbWVudG8pOwoJCX0KCQlyZXR1cm4gbWVtZW50b0xpc3Q7Cgl9CgoJcHJpdmF0ZSBTdHJpbmcgZ2V0Vm1Bcmd1bWVudHMoKSB7CgkJU3RyaW5nIHZtUGFyYW1zID0gZ2V0U2VydmVyRGVmaW5pdGlvbigpLnJlc29sdmVQcm9wZXJ0aWVzKAoJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0YXJ0Vm1QYXJhbWV0ZXJzKCkpOwoJCXJldHVybiB2bVBhcmFtczsKCX0KCglwcml2YXRlIFN0cmluZyBnZXRQcm9ncmFtQXJndW1lbnRzKCkgewoJCVN0cmluZyBzdGFydFBhcmFtcyA9IGdldFNlcnZlckRlZmluaXRpb24oKS5yZXNvbHZlUHJvcGVydGllcygKCQkJCWdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTdGFydFByb2dyYW1Bcmd1bWVudHMoKSk7CgkJcmV0dXJuIHN0YXJ0UGFyYW1zOwoJfQoKCXByaXZhdGUgU3RyaW5nIGdldFdvcmtpbmdEaXJlY3RvcnkoKSB7CgkJU3RyaW5nIHdEaXJlY3RvcnkgPSBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkucmVzb2x2ZVByb3BlcnRpZXMoCgkJCQlnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RhcnRXb3JraW5nRGlyZWN0b3J5KCkpOwoJCXJldHVybiB3RGlyZWN0b3J5OwoKCX0KCglwdWJsaWMgU3RyaW5nIGdldFN0YXJ0Q2xhc3NOYW1lKCkgewoJCXJldHVybiBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RhcnRDbGFzcygpOwoJfQoKCS8qKgoJICogQHJldHVybgoJICovCglwcml2YXRlIE1hcCBnZXRTZXJ2ZXJJbnN0YW5jZVByb3BlcnRpZXMoKSB7CgkJTWFwIGluc3RhbmNlUHJvcGVydGllcyA9IGZMaXZlU2VydmVyLmdldFJ1bnRpbWUoKS5nZXRBdHRyaWJ1dGUoCgkJCQlHZW5lcmljU2VydmVyUnVudGltZS5TRVJWRVJfSU5TVEFOQ0VfUFJPUEVSVElFUywgKE1hcCkgbnVsbCk7CgkJcmV0dXJuIGluc3RhbmNlUHJvcGVydGllczsKCX0KCglwdWJsaWMgU2VydmVyVHlwZURlZmluaXRpb24gZ2V0U2VydmVyRGVmaW5pdGlvbigpIHsKCQkKCQlpZiAoZlNlcnZlckRlZmluaXRpb24gPT0gbnVsbCkKCQkJZlNlcnZlckRlZmluaXRpb24gPSBDb3JlUGx1Z2luLmdldERlZmF1bHQoKQoJCQkJCS5nZXRTZXJ2ZXJUeXBlRGVmaW5pdGlvbk1hbmFnZXIoKQoJCQkJCS5nZXRTZXJ2ZXJSdW50aW1lRGVmaW5pdGlvbigKCQkJCQkJCWZMaXZlU2VydmVyLmdldFJ1bnRpbWUoKS5nZXRBdHRyaWJ1dGUoCgkJCQkJCQkJCUdlbmVyaWNTZXJ2ZXJSdW50aW1lLlNFUlZFUl9ERUZJTklUSU9OX0lELAoJCQkJCQkJCQkiIiksIGdldFNlcnZlckluc3RhbmNlUHJvcGVydGllcygpKTsKCQlyZXR1cm4gZlNlcnZlckRlZmluaXRpb247Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vbml0b3JhYmxlU2VydmVyI2dldFNlcnZlclBvcnRzKCkKCSAqLwoJcHVibGljIExpc3QgZ2V0U2VydmVyUG9ydHMoKSB7CgkJTGlzdCBwb3J0cyA9IG5ldyBBcnJheUxpc3QoKTsKCgkKCQl0cnkgewoJCQlpbnQgcG9ydCA9IEludGVnZXIucGFyc2VJbnQodGhpcy5nZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0UG9ydCgpKTsKCQkJcG9ydHMuYWRkKG5ldyBTZXJ2ZXJQb3J0KCJzZXJ2ZXIiLCAiU2VydmVyIHBvcnQiLCBwb3J0LCAiVENQSVAiKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQl9CgoJCXJldHVybiBwb3J0czsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU3RhcnRhYmxlU2VydmVyI2lzVGVybWluYXRlT25TaHV0ZG93bigpCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzVGVybWluYXRlT25TaHV0ZG93bigpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogU2V0dXAgZm9yIHN0YXJ0aW5nIHRoZSBzZXJ2ZXIuCgkgKiAKCSAqIEBwYXJhbSBsYXVuY2ggSUxhdW5jaAoJICogQHBhcmFtIGxhdW5jaE1vZGUgU3RyaW5nCgkgKiBAcGFyYW0gbW9uaXRvciBJUHJvZ3Jlc3NNb25pdG9yCgkgKi8KCXB1YmxpYyB2b2lkIHNldHVwTGF1bmNoKElMYXVuY2ggbGF1bmNoLCBTdHJpbmcgbGF1bmNoTW9kZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJaWYgKCJ0cnVlIi5lcXVhbHMobGF1bmNoLmdldExhdW5jaENvbmZpZ3VyYXRpb24oKS5nZXRBdHRyaWJ1dGUoQVRUUl9TVE9QLCAiZmFsc2UiKSkpCgkJCXJldHVybjsKLy8JCUlTdGF0dXMgc3RhdHVzID0gZ2V0UnVudGltZSgpLnZhbGlkYXRlKCk7Ci8vCQlpZiAoc3RhdHVzICE9IG51bGwgJiYgIXN0YXR1cy5pc09LKCkpCi8vCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oc3RhdHVzKTsKCgkKCQlJdGVyYXRvciBpdGVyYXRvciA9IHRoaXMuZ2V0U2VydmVyUG9ydHMoKS5pdGVyYXRvcigpOwoJCUlTZXJ2ZXJQb3J0IHNwID0gbnVsbDsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCXNwID0gKElTZXJ2ZXJQb3J0KSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmIChTb2NrZXRVdGlsLmlzUG9ydEluVXNlKHNwLmdldFBvcnQoKSwgNSkpCgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIENvcmVQbHVnaW4uUExVR0lOX0lELCAwLCAiU2VydmVyIFBhcnQgSW4gVXNlICIrc3AuZ2V0UG9ydCgpICsgIi0gIiArc3AuZ2V0TmFtZSgpICxudWxsKSk7CgkJfQoJCQoJCWZMaXZlU2VydmVyLnNldFNlcnZlclN0YXRlKElTZXJ2ZXIuU0VSVkVSX1NUQVJUSU5HKTsKCQoJCS8vIHBpbmcgc2VydmVyIHRvIGNoZWNrIGZvciBzdGFydHVwCgkJdHJ5IHsKCQkJU3RyaW5nIHVybCA9ICJodHRwOi8vbG9jYWxob3N0IjsKCQkJaW50IHBvcnQgPSBzcC5nZXRQb3J0KCk7CgkJCWlmIChwb3J0ICE9IDgwKQoJCQkJdXJsICs9ICI6IiArIHBvcnQ7CgkJCXBpbmcgPSBuZXcgUGluZ1RocmVhZCh0aGlzLCBmTGl2ZVNlcnZlciwgdXJsLCBsYXVuY2hNb2RlKTsKCQkJcGluZy5zdGFydCgpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNhbid0IHBpbmcgZm9yIHNlcnZlciBzdGFydHVwLiIpOwoJCX0KCX0KCQoJLyoqCgkgKiBDbGVhbmx5IHNodXRzIGRvd24gYW5kIHRlcm1pbmF0ZXMgdGhlIHNlcnZlci4KCSAqLwoJcHVibGljIHZvaWQgc3RvcCgpIHsKCQlieXRlIHN0YXRlID0gdGhpcy5mTGl2ZVNlcnZlci5nZXRTZXJ2ZXJTdGF0ZSgpOwoJCWlmIChzdGF0ZSA9PSBJU2VydmVyLlNFUlZFUl9TVE9QUEVEKQoJCQlyZXR1cm47CgkJZWxzZSBpZiAoc3RhdGUgPT0gSVNlcnZlci5TRVJWRVJfU1RBUlRJTkcgfHwgc3RhdGUgPT0gSVNlcnZlci5TRVJWRVJfU1RPUFBJTkcpIHsKCQkJdGVybWluYXRlKCk7CgkJCXJldHVybjsKCQl9CgoJCXRyeSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlN0b3BwaW5nIFNlcnZlciIpOwoJCQlpZiAoc3RhdGUgIT0gSVNlcnZlci5TRVJWRVJfU1RPUFBFRCkKCQkJCWZMaXZlU2VydmVyLnNldFNlcnZlclN0YXRlKElTZXJ2ZXIuU0VSVkVSX1NUT1BQSU5HKTsKCQkJSUxhdW5jaE1hbmFnZXIgbWdyID0gRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLmdldExhdW5jaE1hbmFnZXIoKTsKCgkJCUlMYXVuY2hDb25maWd1cmF0aW9uVHlwZSB0eXBlID0KCQkJCW1nci5nZXRMYXVuY2hDb25maWd1cmF0aW9uVHlwZSgKCQkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuSURfSkFWQV9BUFBMSUNBVElPTik7CgoJCQlTdHJpbmcgbGF1bmNoTmFtZSA9ICJHZW5lcmljU2VydmVyU3RvcHBlciI7CgkJCVN0cmluZyB1bmlxdWVMYXVuY2hOYW1lID0KCQkJCW1nci5nZW5lcmF0ZVVuaXF1ZUxhdW5jaENvbmZpZ3VyYXRpb25OYW1lRnJvbShsYXVuY2hOYW1lKTsKCQkJSUxhdW5jaENvbmZpZ3VyYXRpb24gY29uZiA9IG51bGw7CgoJCQlJTGF1bmNoQ29uZmlndXJhdGlvbltdIGxjaCA9IG1nci5nZXRMYXVuY2hDb25maWd1cmF0aW9ucyh0eXBlKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBsY2gubGVuZ3RoOyBpKyspIHsKCQkJCWlmIChsYXVuY2hOYW1lLmVxdWFscyhsY2hbaV0uZ2V0TmFtZSgpKSkgewoJCQkJCWNvbmYgPSBsY2hbaV07CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCgkJCUlMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd2MgPSBudWxsOwoJCQlpZiAoY29uZiAhPSBudWxsKSB7CgkJCQl3YyA9IGNvbmYuZ2V0V29ya2luZ0NvcHkoKTsKCQkJfSBlbHNlIHsKCQkJCXdjID0gdHlwZS5uZXdJbnN0YW5jZShudWxsLCB1bmlxdWVMYXVuY2hOYW1lKTsKCQkJfQoJCQkvL1RvIHN0b3AgZnJvbSBhcHBlYXJpbmcgaW4gaGlzdG9yeSBsaXN0cwoJCQl3Yy5zZXRBdHRyaWJ1dGUoSURlYnVnVUlDb25zdGFudHMuQVRUUl9QUklWQVRFLCB0cnVlKTsJCQkKCQoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfTUFJTl9UWVBFX05BTUUsCgkJCQkJdGhpcy5nZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RvcENsYXNzKCkpOwoKCQkJR2VuZXJpY1NlcnZlclJ1bnRpbWUgcnVudGltZSA9IChHZW5lcmljU2VydmVyUnVudGltZSkgZkxpdmVTZXJ2ZXIKCQkJCQkuZ2V0UnVudGltZSgpLmdldERlbGVnYXRlKCk7CgoJCQlJVk1JbnN0YWxsIHZtSW5zdGFsbCA9IHJ1bnRpbWUuZ2V0Vk1JbnN0YWxsKCk7CgkJCXdjLnNldEF0dHJpYnV0ZSgKCQkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX1RZUEUsIHJ1bnRpbWUKCQkJCQkJCS5nZXRWTUluc3RhbGxUeXBlSWQoKSk7CgkJCXdjLnNldEF0dHJpYnV0ZSgKCQkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX05BTUUsCgkJCQkJdm1JbnN0YWxsLmdldE5hbWUoKSk7CgoJCQlzZXR1cExhdW5jaENsYXNzcGF0aCh3Yywgdm1JbnN0YWxsKTsKCgkJCXdjLnNldEF0dHJpYnV0ZSgKCQkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9XT1JLSU5HX0RJUkVDVE9SWSwKCQkJCQlnZXRXb3JraW5nRGlyZWN0b3J5KCkpOwoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfUFJPR1JBTV9BUkdVTUVOVFMsCgkJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLnJlc29sdmVQcm9wZXJ0aWVzKAoJCQkJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3BQcm9ncmFtQXJndW1lbnRzKCkpKTsKCQkJd2Muc2V0QXR0cmlidXRlKAoJCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1ZNX0FSR1VNRU5UUywKCQkJCQlnZXRTZXJ2ZXJEZWZpbml0aW9uKCkucmVzb2x2ZVByb3BlcnRpZXMoCgkJCQkJCQlnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RvcFZtUGFyYW1ldGVycygpKSk7CQkJCQoJCQl3Yy5zZXRBdHRyaWJ1dGUoQVRUUl9TVE9QLCAidHJ1ZSIpOwoJCQl3Yy5sYXVuY2goSUxhdW5jaE1hbmFnZXIuUlVOX01PREUsIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIHN0b3BwaW5nIFNlcnZlciIsIGUpOwoJCX0KCX0KCgoJLyoqCgkgKiBAcGFyYW0gd2MKCSAqIEBwYXJhbSB2bUluc3RhbGwKCSAqLwoJcHJpdmF0ZSB2b2lkIHNldHVwTGF1bmNoQ2xhc3NwYXRoKElMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd2MsIElWTUluc3RhbGwgdm1JbnN0YWxsKSB7CgkJTGlzdCBjcCA9IGdldENsYXNzcGF0aE1lbWVudG9zKCk7CgoJCS8vIGFkZCB0b29scy5qYXIgdG8gdGhlIHBhdGgKCQlpZiAodm1JbnN0YWxsICE9IG51bGwpIHsKCQkJdHJ5IHsKCQkJCWNwCgkJCQkJCS5hZGQoSmF2YVJ1bnRpbWUKCQkJCQkJCQkubmV3UnVudGltZUNvbnRhaW5lckNsYXNzcGF0aEVudHJ5KAoJCQkJCQkJCQkJbmV3IFBhdGgoSmF2YVJ1bnRpbWUuSlJFX0NPTlRBSU5FUikKCQkJCQkJCQkJCQkJLmFwcGVuZCgKCQkJCQkJCQkJCQkJCQkib3JnLmVjbGlwc2UuamR0LmludGVybmFsLmRlYnVnLnVpLmxhdW5jaGVyLlN0YW5kYXJkVk1UeXBlIikKCQkJCQkJCQkJCQkJLmFwcGVuZCh2bUluc3RhbGwuZ2V0TmFtZSgpKSwKCQkJCQkJCQkJCUlSdW50aW1lQ2xhc3NwYXRoRW50cnkuQk9PVFNUUkFQX0NMQVNTRVMpCgkJCQkJCQkJLmdldE1lbWVudG8oKSk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCX0KCgkJCUlQYXRoIGpyZVBhdGggPSBuZXcgUGF0aCh2bUluc3RhbGwuZ2V0SW5zdGFsbExvY2F0aW9uKCkKCQkJCQkuZ2V0QWJzb2x1dGVQYXRoKCkpOwoJCQlpZiAoanJlUGF0aCAhPSBudWxsKSB7CgkJCQlJUGF0aCB0b29sc1BhdGggPSBqcmVQYXRoLmFwcGVuZCgibGliIikuYXBwZW5kKCJ0b29scy5qYXIiKTsKCQkJCWlmICh0b29sc1BhdGgudG9GaWxlKCkuZXhpc3RzKCkpIHsKCQkJCQl0cnkgewoJCQkJCQljcC5hZGQoSmF2YVJ1bnRpbWUubmV3QXJjaGl2ZVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSgKCQkJCQkJCQl0b29sc1BhdGgpLmdldE1lbWVudG8oKSk7CgkJCQkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlMSkgewoJCQkJCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNhdGNoIGJsb2NrCgkJCQkJCWUxLnByaW50U3RhY2tUcmFjZSgpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJd2Muc2V0QXR0cmlidXRlKAoJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfQ0xBU1NQQVRILCBjcCk7CgkJd2Muc2V0QXR0cmlidXRlKAoJCQkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9ERUZBVUxUX0NMQVNTUEFUSCwKCQkJCQkJZmFsc2UpOwoJfQoKCS8qKgoJICogVGVybWluYXRlcyB0aGUgc2VydmVyLgoJICovCglwdWJsaWMgdm9pZCB0ZXJtaW5hdGUoKSB7CgkJaWYgKGZMaXZlU2VydmVyLmdldFNlcnZlclN0YXRlKCkgPT0gSVNlcnZlci5TRVJWRVJfU1RPUFBFRCkKCQkJcmV0dXJuOwoKCQl0cnkgewoJCQlmTGl2ZVNlcnZlci5zZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNFUlZFUl9TVE9QUElORyk7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIktpbGxpbmcgdGhlIFNlcnZlciBwcm9jZXNzIik7CgkJCWlmIChwcm9jZXNzICE9IG51bGwgJiYgIXByb2Nlc3MuaXNUZXJtaW5hdGVkKCkpIHsKCQkJCXByb2Nlc3MudGVybWluYXRlKCk7CgkJCQlzdG9wSW1wbCgpOwoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3Iga2lsbGluZyB0aGUgcHJvY2VzcyIsIGUpOwoJCX0KCX0KCQoJcHJvdGVjdGVkIHZvaWQgc3RvcEltcGwoKSB7CgkJaWYgKHBpbmcgIT0gbnVsbCkgewoJCQlwaW5nLnN0b3BQaW5naW5nKCk7CgkJCXBpbmcgPSBudWxsOwoJCX0KCQlpZiAocHJvY2VzcyAhPSBudWxsKSB7CgkJCXByb2Nlc3MgPSBudWxsOwoJCQlEZWJ1Z1BsdWdpbi5nZXREZWZhdWx0KCkucmVtb3ZlRGVidWdFdmVudExpc3RlbmVyKHByb2Nlc3NMaXN0ZW5lcik7CgkJCXByb2Nlc3NMaXN0ZW5lciA9IG51bGw7CgkJfQoJCWZMaXZlU2VydmVyLnNldFNlcnZlclN0YXRlKElTZXJ2ZXIuU0VSVkVSX1NUT1BQRUQpOwoJfQkKCXB1YmxpYyB2b2lkIHNldFByb2Nlc3MoZmluYWwgSVByb2Nlc3MgbmV3UHJvY2VzcykgewoJCWlmIChwcm9jZXNzICE9IG51bGwpCgkJCXJldHVybjsKCgkJcHJvY2VzcyA9IG5ld1Byb2Nlc3M7CgkJcHJvY2Vzc0xpc3RlbmVyID0gbmV3IElEZWJ1Z0V2ZW50U2V0TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIGhhbmRsZURlYnVnRXZlbnRzKERlYnVnRXZlbnRbXSBldmVudHMpIHsKCQkJCWlmIChldmVudHMgIT0gbnVsbCkgewoJCQkJCWludCBzaXplID0gZXZlbnRzLmxlbmd0aDsKCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCQlpZiAocHJvY2Vzcy5lcXVhbHMoZXZlbnRzW2ldLmdldFNvdXJjZSgpKSAmJiBldmVudHNbaV0uZ2V0S2luZCgpID09IERlYnVnRXZlbnQuVEVSTUlOQVRFKSB7CgkJCQkJCQlEZWJ1Z1BsdWdpbi5nZXREZWZhdWx0KCkucmVtb3ZlRGVidWdFdmVudExpc3RlbmVyKHRoaXMpOwoJCQkJCQkJc3RvcEltcGwoKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX07CgkJRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLmFkZERlYnVnRXZlbnRMaXN0ZW5lcihwcm9jZXNzTGlzdGVuZXIpOwoJfQoJCglwdWJsaWMgaW50IGdldFN0YXJ0VGltZW91dCgpIHsKCQlyZXR1cm4gMzAwMDAwOwoJfQoJCglwdWJsaWMgaW50IGdldFN0b3BUaW1lb3V0KCkgewoJCXJldHVybiAzMDAwMDA7Cgl9CgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLnd0cC5zZXJ2ZXIuY29yZS5tb2RlbC5JVVJMUHJvdmlkZXIjZ2V0TW9kdWxlUm9vdFVSTChvcmcuZWNsaXBzZS53dHAuc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZSkKCSAqLwoJcHVibGljIFVSTCBnZXRNb2R1bGVSb290VVJMKElNb2R1bGUgbW9kdWxlKSB7CgoJCXRyeSB7CgkJCWlmIChtb2R1bGUgPT0gbnVsbCB8fCAhKG1vZHVsZSBpbnN0YW5jZW9mIElXZWJNb2R1bGUpKQoJCQkJcmV0dXJuIG51bGw7CgoJCQlJU2VydmVyQ29uZmlndXJhdGlvbiBzZXJ2ZXJDb25maWcgPSBmTGl2ZVNlcnZlcgoJCQkJCS5nZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCk7CgkJCWlmIChzZXJ2ZXJDb25maWcgPT0gbnVsbCkKCQkJCXJldHVybiBudWxsOwoKCQkJU3RyaW5nIHVybCA9ICJodHRwOi8vbG9jYWxob3N0IjsKCQkJaW50IHBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRQb3J0KCkpOwoJCQlwb3J0ID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJNb25pdG9yTWFuYWdlcigpLmdldE1vbml0b3JlZFBvcnQoCgkJCQkJZkxpdmVTZXJ2ZXIsIHBvcnQsICJ3ZWIiKTsKCQkJaWYgKHBvcnQgIT0gODApCgkJCQl1cmwgKz0gIjoiICsgcG9ydDsKCgkJCXVybCArPSAiLyIrbW9kdWxlLmdldE5hbWUoKTsKCgkJCWlmICghdXJsLmVuZHNXaXRoKCIvIikpCgkJCQl1cmwgKz0gIi8iOwoKCQkJcmV0dXJuIG5ldyBVUkwodXJsKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZSgiQ291bGQgbm90IGdldCByb290IFVSTCIsIGUpOwoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJfQoKfQ==