LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBHb3JrZW0gRXJjYW4gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE5hY2kgTS4gRGFpCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBFVEVSQVRJT04gQS5TLiBPUgogKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgogKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAogKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQogKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4gIEZvciBtb3JlCiAqIGluZm9ybWF0aW9uIG9uIGV0ZXJhdGlvbiwgcGxlYXNlIHNlZQogKiA8aHR0cDovL3d3dy5ldGVyYXRpb24uY29tLz4uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmludGVybmFsLmNvcmU7CgppbXBvcnQgamF2YS5uZXQuVVJMOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLk51bGxQcm9ncmVzc01vbml0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5TdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLkRlYnVnRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLkRlYnVnUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JRGVidWdFdmVudFNldExpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoQ29uZmlndXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25UeXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5OwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoTWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUubW9kZWwuSVByb2Nlc3M7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy51aS5JRGVidWdVSUNvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JUnVudGltZUNsYXNzcGF0aEVudHJ5OwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JVk1JbnN0YWxsOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5KYXZhUnVudGltZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuZ2VuZXJpYy5jb3JlLkNvcmVQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuaW50ZXJuYWwueG1sLlNlcnZlclR5cGVEZWZpbml0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLm1vZHVsZXMuSjJlZVNwZWNNb2R1bGVGYWN0b3J5RGVsZWdhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmoyZWUuSVdlYk1vZHVsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJDb25maWd1cmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJTdGF0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JVGFzazsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5TZXJ2ZXJDb3JlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZUV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGVGYWN0b3J5RXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vbml0b3JhYmxlU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklQdWJsaXNoZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJQb3J0OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTdGFydGFibGVTZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVVSTFByb3ZpZGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLnJlc291cmNlcy5JTW9kdWxlUmVzb3VyY2VEZWx0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS51dGlsLlNlcnZlclBvcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUudXRpbC5Tb2NrZXRVdGlsOwoKLyoqCiAqIEdlbmVyaWMgWE1MIGJhc2VkIHNlcnZlciBpbXBsZW1lbnRhdGlvbi4KICogCiAqIEBhdXRob3IgR29ya2VtIEVyY2FuCiAqLwpwdWJsaWMgY2xhc3MgR2VuZXJpY1NlcnZlciBpbXBsZW1lbnRzIElTZXJ2ZXJEZWxlZ2F0ZSwgSVN0YXJ0YWJsZVNlcnZlciwgSU1vbml0b3JhYmxlU2VydmVyLElVUkxQcm92aWRlciB7Cglwcml2YXRlIElTZXJ2ZXJTdGF0ZSBmTGl2ZVNlcnZlcjsKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX1NUT1AgPSAic3RvcC1zZXJ2ZXIiOwoJCgkvLyB0aGUgdGhyZWFkIHVzZWQgdG8gcGluZyB0aGUgc2VydmVyIHRvIGNoZWNrIGZvciBzdGFydHVwCglwcm90ZWN0ZWQgdHJhbnNpZW50IFBpbmdUaHJlYWQgcGluZyA9IG51bGw7Cglwcm90ZWN0ZWQgdHJhbnNpZW50IElQcm9jZXNzIHByb2Nlc3M7Cglwcm90ZWN0ZWQgdHJhbnNpZW50IElEZWJ1Z0V2ZW50U2V0TGlzdGVuZXIgcHJvY2Vzc0xpc3RlbmVyOwoJCglwcml2YXRlIFNlcnZlclR5cGVEZWZpbml0aW9uIGZTZXJ2ZXJEZWZpbml0aW9uOwoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNpbml0aWFsaXplKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyU3RhdGUpCgkgKi8KCXB1YmxpYyB2b2lkIGluaXRpYWxpemUoSVNlcnZlclN0YXRlIGxpdmVTZXJ2ZXIpIHsKCQl0aGlzLmZMaXZlU2VydmVyID0gbGl2ZVNlcnZlcjsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjZGlzcG9zZSgpCgkgKi8KCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJdGhpcy5mTGl2ZVNlcnZlciA9IG51bGw7CgoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcHJvamVjdCBwdWJsaXNoZXIgdGhhdCBjYW4gYmUgdXNlZCB0bwoJICogcHVibGlzaCB0aGUgZ2l2ZW4gcHJvamVjdC4KCSAqCgkgKiBAcGFyYW0gcHJvamVjdCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUHJvamVjdAoJICogQHJldHVybiBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVByb2plY3RQdWJsaXNoZXIKCSAqLwoJcHVibGljIElQdWJsaXNoZXIgZ2V0UHVibGlzaGVyKExpc3QgcGFyZW50cywgSU1vZHVsZSBtb2R1bGUpIHsKCQlyZXR1cm4gbmV3IEFudFB1Ymxpc2hlcihwYXJlbnRzLCBtb2R1bGUsIHRoaXMuZ2V0U2VydmVyRGVmaW5pdGlvbigpKTsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjdXBkYXRlQ29uZmlndXJhdGlvbigpCgkgKi8KCXB1YmxpYyB2b2lkIHVwZGF0ZUNvbmZpZ3VyYXRpb24oKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAidXBkYXRlQ29uZmlndXJhdGlvbiIgKyB0aGlzKTsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjdXBkYXRlTW9kdWxlKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlLAoJICogICAgICBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUucmVzb3VyY2VzLklNb2R1bGVSZXNvdXJjZURlbHRhKQoJICovCglwdWJsaWMgdm9pZCB1cGRhdGVNb2R1bGUoSU1vZHVsZSBtb2R1bGUsIElNb2R1bGVSZXNvdXJjZURlbHRhIGRlbHRhKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIkNvbmZpZ3VyYXRpb24gdXBkYXRlZCAiICsgdGhpcyk7CgkJLy9zZXRDb25maWd1cmF0aW9uU3luY1N0YXRlKFNZTkNfU1RBVEVfRElSVFkpOwoJCS8vc2V0UmVzdGFydE5lZWRlZCh0cnVlKTsKCgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3B1Ymxpc2hTdGFydChvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIElTdGF0dXMgcHVibGlzaFN0YXJ0KElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIENvcmVQbHVnaW4uUExVR0lOX0lELCAwLCAiUHVibGlzaGluZ1N0YXJ0ZWQiLCBudWxsKTsKCX0KCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjcHVibGlzaENvbmZpZ3VyYXRpb24ob3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3IpCgkgKi8KCXB1YmxpYyBJU3RhdHVzIHB1Ymxpc2hDb25maWd1cmF0aW9uKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoKCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgIlB1Ymxpc2hlZCBDb25maWd1cmF0aW9uIiwgbnVsbCk7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3B1Ymxpc2hTdG9wKG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgSVN0YXR1cyBwdWJsaXNoU3RvcChJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlmTGl2ZVNlcnZlci5zZXRDb25maWd1cmF0aW9uU3luY1N0YXRlKElTZXJ2ZXIuU1lOQ19TVEFURV9JTl9TWU5DKTsKCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLk9LLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgIlB1Ymxpc2hlZCBDb25maWd1cmF0aW9uIiwgbnVsbCk7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI2Nhbk1vZGlmeU1vZHVsZXMob3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGVbXSwKCSAqICAgICAgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGVbXSkKCSAqLwoJcHVibGljIElTdGF0dXMgY2FuTW9kaWZ5TW9kdWxlcyhJTW9kdWxlW10gYWRkLCBJTW9kdWxlW10gcmVtb3ZlKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIENvcmVQbHVnaW4uUExVR0lOX0lELCAwLCAiQ2FuTW9kaWZ5TW9kdWxlcyIsIG51bGwpOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNnZXRNb2R1bGVzKCkKCSAqLwoJcHVibGljIElNb2R1bGVbXSBnZXRNb2R1bGVzKCkgewoJCS8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKCQlMaXN0IGxpc3QgPSAgSjJlZVNwZWNNb2R1bGVGYWN0b3J5RGVsZWdhdGUuZ2V0SW5zdGFuY2UoKS5nZXRNb2R1bGVzKCk7CgkJcmV0dXJuIChJTW9kdWxlW10pbGlzdC50b0FycmF5KG5ldyBJTW9kdWxlW2xpc3Quc2l6ZSgpXSk7Cgl9CgoJCglwcm90ZWN0ZWQgSVdlYk1vZHVsZSBnZXRXZWJNb2R1bGUoSVByb2plY3QgcHJvamVjdCkgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCgkJcmV0dXJuIG51bGw7Cgl9CgoKCQkKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNnZXRNb2R1bGVTdGF0ZShvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZSkKCSAqLwoJcHVibGljIGJ5dGUgZ2V0TW9kdWxlU3RhdGUoSU1vZHVsZSBtb2R1bGUpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJcmV0dXJuIElTZXJ2ZXIuTU9EVUxFX1NUQVRFX1NUQVJURUQ7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI2dldFJlcGFpckNvbW1hbmRzKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlRmFjdG9yeUV2ZW50W10sCgkgKiAgICAgIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlRXZlbnRbXSkKCSAqLwoJcHVibGljIElUYXNrW10gZ2V0UmVwYWlyQ29tbWFuZHMoSU1vZHVsZUZhY3RvcnlFdmVudFtdIGZhY3RvcnlFdmVudCwKCQkJSU1vZHVsZUV2ZW50W10gbW9kdWxlRXZlbnQpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI2dldENoaWxkTW9kdWxlcyhvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZSkKCSAqLwoJcHVibGljIExpc3QgZ2V0Q2hpbGRNb2R1bGVzKElNb2R1bGUgbW9kdWxlKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCXJldHVybiBudWxsOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNnZXRQYXJlbnRNb2R1bGVzKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlKQoJICovCglwdWJsaWMgTGlzdCBnZXRQYXJlbnRNb2R1bGVzKElNb2R1bGUgbW9kdWxlKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJCS8vRklYTUUgVGhpcyBpcyB2YWxpZCBmb3Igb25seSB3ZWIgbW9kdWxlcy4gQSBnZW5lcmljIHNlcnZlciBzaG91bGQgc3VwcG9ydCBhbnkgCgkJCS8vIGtpbmQgb2YgajJlZSBtb2R1bGUuIEZpeCB0aGlzIGFmdGVyIHRoZSBzZXJ2ZXIgYXJjaGl0ZWN0dXJlcyBhcmUgZGV0ZXJtaW5lZC4KCQlpZiAobW9kdWxlIGluc3RhbmNlb2YgSVdlYk1vZHVsZSkgewoJCQlJV2ViTW9kdWxlIHdlYk1vZHVsZSA9IChJV2ViTW9kdWxlKSBtb2R1bGU7CgkJCUlTdGF0dXMgc3RhdHVzID0gY2FuTW9kaWZ5TW9kdWxlcyhuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sIG51bGwpOwoJCQlpZiAoc3RhdHVzID09IG51bGwgfHwgIXN0YXR1cy5pc09LKCkpCgkJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihzdGF0dXMpOwoJCQlBcnJheUxpc3QgbCA9IG5ldyBBcnJheUxpc3QoKTsKCQkJbC5hZGQod2ViTW9kdWxlKTsKCQkJcmV0dXJuIGw7CgkJfQoJCXJldHVybiBudWxsOwoJCgl9CgoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI3NldExhdW5jaERlZmF1bHRzKG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSkKCSAqLwoJcHVibGljIHZvaWQgc2V0TGF1bmNoRGVmYXVsdHMoSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSB3b3JraW5nQ29weSkgewoJCWZMaXZlU2VydmVyLmdldFJ1bnRpbWUoKS5nZXREZWxlZ2F0ZSgpOwoJCXdvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZSgKCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX01BSU5fVFlQRV9OQU1FLAoJCQkJZ2V0U3RhcnRDbGFzc05hbWUoKSk7CgoJCUdlbmVyaWNTZXJ2ZXJSdW50aW1lIHJ1bnRpbWUgPSAoR2VuZXJpY1NlcnZlclJ1bnRpbWUpIGZMaXZlU2VydmVyCgkJCQkuZ2V0UnVudGltZSgpLmdldERlbGVnYXRlKCk7CgoJCUlWTUluc3RhbGwgdm1JbnN0YWxsID0gcnVudGltZS5nZXRWTUluc3RhbGwoKTsKCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX1RZUEUsIHJ1bnRpbWUKCQkJCQkJLmdldFZNSW5zdGFsbFR5cGVJZCgpKTsKCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX05BTUUsCgkJCQl2bUluc3RhbGwuZ2V0TmFtZSgpKTsKCgkJc2V0dXBMYXVuY2hDbGFzc3BhdGgod29ya2luZ0NvcHksIHZtSW5zdGFsbCk7CgoKCQl3b3JraW5nQ29weS5zZXRBdHRyaWJ1dGUoCgkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9XT1JLSU5HX0RJUkVDVE9SWSwKCQkJCWdldFdvcmtpbmdEaXJlY3RvcnkoKSk7CgkJd29ya2luZ0NvcHkuc2V0QXR0cmlidXRlKAoJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfUFJPR1JBTV9BUkdVTUVOVFMsCgkJCQlnZXRQcm9ncmFtQXJndW1lbnRzKCkpOwoJCXdvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZSgKCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1ZNX0FSR1VNRU5UUywKCQkJCWdldFZtQXJndW1lbnRzKCkpOwoKCQkvL3dvcmtpbmdDb3B5LnNldEF0dHJpYnV0ZShJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9WTV9JTlNUQUxMX1RZUEVfU1BFQ0lGSUNfQVRUUlNfTUFQLCk7CgoJfQoKCXByaXZhdGUgTGlzdCBnZXRDbGFzc3BhdGhNZW1lbnRvcygpIHsKCQlyZXR1cm4gZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFNlcnZlckNsYXNzcGF0aE1lbWVudG9zKCk7Cgl9CgoJcHJpdmF0ZSBTdHJpbmcgZ2V0Vm1Bcmd1bWVudHMoKSB7CgkJcmV0dXJuIGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTdGFydFZtUGFyYW1ldGVycygpOwoJfQoKCXByaXZhdGUgU3RyaW5nIGdldFByb2dyYW1Bcmd1bWVudHMoKSB7CgkJcmV0dXJuIGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRTdGFydFByb2dyYW1Bcmd1bWVudHMoKTsKCX0KCglwcml2YXRlIFN0cmluZyBnZXRXb3JraW5nRGlyZWN0b3J5KCkgewoJCXJldHVybiBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0U3RhcnRXb3JraW5nRGlyZWN0b3J5KCk7Cgl9CgoJcHVibGljIFN0cmluZyBnZXRTdGFydENsYXNzTmFtZSgpIHsKCQlyZXR1cm4gZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0YXJ0Q2xhc3MoKTsKCX0KCgkvKioKCSAqIEByZXR1cm4KCSAqLwoJcHJpdmF0ZSBNYXAgZ2V0U2VydmVySW5zdGFuY2VQcm9wZXJ0aWVzKCkgewoJCU1hcCBpbnN0YW5jZVByb3BlcnRpZXMgPSBmTGl2ZVNlcnZlci5nZXRSdW50aW1lKCkuZ2V0QXR0cmlidXRlKAoJCQkJR2VuZXJpY1NlcnZlclJ1bnRpbWUuU0VSVkVSX0lOU1RBTkNFX1BST1BFUlRJRVMsIChNYXApIG51bGwpOwoJCXJldHVybiBpbnN0YW5jZVByb3BlcnRpZXM7Cgl9CgoJcHVibGljIFNlcnZlclR5cGVEZWZpbml0aW9uIGdldFNlcnZlckRlZmluaXRpb24oKSB7CgkJCgkJaWYgKGZTZXJ2ZXJEZWZpbml0aW9uID09IG51bGwpCgkJCWZTZXJ2ZXJEZWZpbml0aW9uID0gQ29yZVBsdWdpbi5nZXREZWZhdWx0KCkKCQkJCQkuZ2V0U2VydmVyVHlwZURlZmluaXRpb25NYW5hZ2VyKCkKCQkJCQkuZ2V0U2VydmVyUnVudGltZURlZmluaXRpb24oCgkJCQkJCQlmTGl2ZVNlcnZlci5nZXRSdW50aW1lKCkuZ2V0QXR0cmlidXRlKAoJCQkJCQkJCQlHZW5lcmljU2VydmVyUnVudGltZS5TRVJWRVJfREVGSU5JVElPTl9JRCwKCQkJCQkJCQkJIiIpLCBnZXRTZXJ2ZXJJbnN0YW5jZVByb3BlcnRpZXMoKSk7CgkJcmV0dXJuIGZTZXJ2ZXJEZWZpbml0aW9uOwoJfQoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklNb25pdG9yYWJsZVNlcnZlciNnZXRTZXJ2ZXJQb3J0cygpCgkgKi8KCXB1YmxpYyBMaXN0IGdldFNlcnZlclBvcnRzKCkgewoJCUxpc3QgcG9ydHMgPSBuZXcgQXJyYXlMaXN0KCk7CgoJCgkJdHJ5IHsKCQkJaW50IHBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KHRoaXMuZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFBvcnQoKSk7CgkJCXBvcnRzLmFkZChuZXcgU2VydmVyUG9ydCgic2VydmVyIiwgIlNlcnZlciBwb3J0IiwgcG9ydCwgIlRDUElQIikpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJfQoKCQlyZXR1cm4gcG9ydHM7Cgl9CgoJLyogKG5vbi1KYXZhZG9jKQoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVN0YXJ0YWJsZVNlcnZlciNpc1Rlcm1pbmF0ZU9uU2h1dGRvd24oKQoJICovCglwdWJsaWMgYm9vbGVhbiBpc1Rlcm1pbmF0ZU9uU2h1dGRvd24oKSB7CgkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBtZXRob2Qgc3R1YgoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFNldHVwIGZvciBzdGFydGluZyB0aGUgc2VydmVyLgoJICogCgkgKiBAcGFyYW0gbGF1bmNoIElMYXVuY2gKCSAqIEBwYXJhbSBsYXVuY2hNb2RlIFN0cmluZwoJICogQHBhcmFtIG1vbml0b3IgSVByb2dyZXNzTW9uaXRvcgoJICovCglwdWJsaWMgdm9pZCBzZXR1cExhdW5jaChJTGF1bmNoIGxhdW5jaCwgU3RyaW5nIGxhdW5jaE1vZGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWlmICgidHJ1ZSIuZXF1YWxzKGxhdW5jaC5nZXRMYXVuY2hDb25maWd1cmF0aW9uKCkuZ2V0QXR0cmlidXRlKEFUVFJfU1RPUCwgImZhbHNlIikpKQoJCQlyZXR1cm47Ci8vCQlJU3RhdHVzIHN0YXR1cyA9IGdldFJ1bnRpbWUoKS52YWxpZGF0ZSgpOwovLwkJaWYgKHN0YXR1cyAhPSBudWxsICYmICFzdGF0dXMuaXNPSygpKQovLwkJCXRocm93IG5ldyBDb3JlRXhjZXB0aW9uKHN0YXR1cyk7CgoJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSB0aGlzLmdldFNlcnZlclBvcnRzKCkuaXRlcmF0b3IoKTsKCQlJU2VydmVyUG9ydCBzcCA9IG51bGw7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlzcCA9IChJU2VydmVyUG9ydCkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoU29ja2V0VXRpbC5pc1BvcnRJblVzZShzcC5nZXRQb3J0KCksIDUpKQoJCQkJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgIlNlcnZlciBQYXJ0IEluIFVzZSAiK3NwLmdldFBvcnQoKSArICItICIgK3NwLmdldE5hbWUoKSAsbnVsbCkpOwoJCX0KCQkKCQlmTGl2ZVNlcnZlci5zZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNFUlZFUl9TVEFSVElORyk7CgkKCQkvLyBwaW5nIHNlcnZlciB0byBjaGVjayBmb3Igc3RhcnR1cAoJCXRyeSB7CgkJCVN0cmluZyB1cmwgPSAiaHR0cDovL2xvY2FsaG9zdCI7CgkJCWludCBwb3J0ID0gc3AuZ2V0UG9ydCgpOwoJCQlpZiAocG9ydCAhPSA4MCkKCQkJCXVybCArPSAiOiIgKyBwb3J0OwoJCQlwaW5nID0gbmV3IFBpbmdUaHJlYWQodGhpcywgZkxpdmVTZXJ2ZXIsIHVybCwgbGF1bmNoTW9kZSk7CgkJCXBpbmcuc3RhcnQoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDYW4ndCBwaW5nIGZvciBzZXJ2ZXIgc3RhcnR1cC4iKTsKCQl9Cgl9CgkKCS8qKgoJICogQ2xlYW5seSBzaHV0cyBkb3duIGFuZCB0ZXJtaW5hdGVzIHRoZSBzZXJ2ZXIuCgkgKi8KCXB1YmxpYyB2b2lkIHN0b3AoKSB7CgkJYnl0ZSBzdGF0ZSA9IHRoaXMuZkxpdmVTZXJ2ZXIuZ2V0U2VydmVyU3RhdGUoKTsKCQlpZiAoc3RhdGUgPT0gSVNlcnZlci5TRVJWRVJfU1RPUFBFRCkKCQkJcmV0dXJuOwoJCWVsc2UgaWYgKHN0YXRlID09IElTZXJ2ZXIuU0VSVkVSX1NUQVJUSU5HIHx8IHN0YXRlID09IElTZXJ2ZXIuU0VSVkVSX1NUT1BQSU5HKSB7CgkJCXRlcm1pbmF0ZSgpOwoJCQlyZXR1cm47CgkJfQoKCQl0cnkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJTdG9wcGluZyBTZXJ2ZXIiKTsKCQkJaWYgKHN0YXRlICE9IElTZXJ2ZXIuU0VSVkVSX1NUT1BQRUQpCgkJCQlmTGl2ZVNlcnZlci5zZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNFUlZFUl9TVE9QUElORyk7CgkJCUlMYXVuY2hNYW5hZ2VyIG1nciA9IERlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5nZXRMYXVuY2hNYW5hZ2VyKCk7CgoJCQlJTGF1bmNoQ29uZmlndXJhdGlvblR5cGUgdHlwZSA9CgkJCQltZ3IuZ2V0TGF1bmNoQ29uZmlndXJhdGlvblR5cGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLklEX0pBVkFfQVBQTElDQVRJT04pOwoKCQkJU3RyaW5nIGxhdW5jaE5hbWUgPSAiR2VuZXJpY1NlcnZlclN0b3BwZXIiOwoJCQlTdHJpbmcgdW5pcXVlTGF1bmNoTmFtZSA9CgkJCQltZ3IuZ2VuZXJhdGVVbmlxdWVMYXVuY2hDb25maWd1cmF0aW9uTmFtZUZyb20obGF1bmNoTmFtZSk7CgkJCUlMYXVuY2hDb25maWd1cmF0aW9uIGNvbmYgPSBudWxsOwoKCQkJSUxhdW5jaENvbmZpZ3VyYXRpb25bXSBsY2ggPSBtZ3IuZ2V0TGF1bmNoQ29uZmlndXJhdGlvbnModHlwZSk7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGNoLmxlbmd0aDsgaSsrKSB7CgkJCQlpZiAobGF1bmNoTmFtZS5lcXVhbHMobGNoW2ldLmdldE5hbWUoKSkpIHsKCQkJCQljb25mID0gbGNoW2ldOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgoJCQlJTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5IHdjID0gbnVsbDsKCQkJaWYgKGNvbmYgIT0gbnVsbCkgewoJCQkJd2MgPSBjb25mLmdldFdvcmtpbmdDb3B5KCk7CgkJCX0gZWxzZSB7CgkJCQl3YyA9IHR5cGUubmV3SW5zdGFuY2UobnVsbCwgdW5pcXVlTGF1bmNoTmFtZSk7CgkJCX0KCQkJLy9UbyBzdG9wIGZyb20gYXBwZWFyaW5nIGluIGhpc3RvcnkgbGlzdHMKCQkJd2Muc2V0QXR0cmlidXRlKElEZWJ1Z1VJQ29uc3RhbnRzLkFUVFJfUFJJVkFURSwgdHJ1ZSk7CQkJCgkKCQkJd2Muc2V0QXR0cmlidXRlKAoJCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX01BSU5fVFlQRV9OQU1FLAoJCQkJCXRoaXMuZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3BDbGFzcygpKTsKCgkJCUdlbmVyaWNTZXJ2ZXJSdW50aW1lIHJ1bnRpbWUgPSAoR2VuZXJpY1NlcnZlclJ1bnRpbWUpIGZMaXZlU2VydmVyCgkJCQkJLmdldFJ1bnRpbWUoKS5nZXREZWxlZ2F0ZSgpOwoKCQkJSVZNSW5zdGFsbCB2bUluc3RhbGwgPSBydW50aW1lLmdldFZNSW5zdGFsbCgpOwoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fSU5TVEFMTF9UWVBFLCBydW50aW1lCgkJCQkJCQkuZ2V0Vk1JbnN0YWxsVHlwZUlkKCkpOwoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fSU5TVEFMTF9OQU1FLAoJCQkJCXZtSW5zdGFsbC5nZXROYW1lKCkpOwoKCQkJc2V0dXBMYXVuY2hDbGFzc3BhdGgod2MsIHZtSW5zdGFsbCk7CgoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfV09SS0lOR19ESVJFQ1RPUlksCgkJCQkJZ2V0V29ya2luZ0RpcmVjdG9yeSgpKTsKCQkJd2Muc2V0QXR0cmlidXRlKAoJCQkJCUlKYXZhTGF1bmNoQ29uZmlndXJhdGlvbkNvbnN0YW50cy5BVFRSX1BST0dSQU1fQVJHVU1FTlRTLAoJCQkJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3BQcm9ncmFtQXJndW1lbnRzKCkpOwoJCQl3Yy5zZXRBdHRyaWJ1dGUoCgkJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfVk1fQVJHVU1FTlRTLAoJCQkJCQkJZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFN0b3BWbVBhcmFtZXRlcnMoKSk7CQkJCQoJCQl3Yy5zZXRBdHRyaWJ1dGUoQVRUUl9TVE9QLCAidHJ1ZSIpOwoJCQl3Yy5sYXVuY2goSUxhdW5jaE1hbmFnZXIuUlVOX01PREUsIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIHN0b3BwaW5nIFNlcnZlciIsIGUpOwoJCX0KCX0KCgoJLyoqCgkgKiBAcGFyYW0gd2MKCSAqIEBwYXJhbSB2bUluc3RhbGwKCSAqLwoJcHJpdmF0ZSB2b2lkIHNldHVwTGF1bmNoQ2xhc3NwYXRoKElMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd2MsIElWTUluc3RhbGwgdm1JbnN0YWxsKSB7CgkJTGlzdCBjcCA9IGdldENsYXNzcGF0aE1lbWVudG9zKCk7CgoJCS8vIGFkZCB0b29scy5qYXIgdG8gdGhlIHBhdGgKCQlpZiAodm1JbnN0YWxsICE9IG51bGwpIHsKCQkJdHJ5IHsKCQkJCWNwCgkJCQkJCS5hZGQoSmF2YVJ1bnRpbWUKCQkJCQkJCQkubmV3UnVudGltZUNvbnRhaW5lckNsYXNzcGF0aEVudHJ5KAoJCQkJCQkJCQkJbmV3IFBhdGgoSmF2YVJ1bnRpbWUuSlJFX0NPTlRBSU5FUikKCQkJCQkJCQkJCQkJLmFwcGVuZCgKCQkJCQkJCQkJCQkJCQkib3JnLmVjbGlwc2UuamR0LmludGVybmFsLmRlYnVnLnVpLmxhdW5jaGVyLlN0YW5kYXJkVk1UeXBlIikKCQkJCQkJCQkJCQkJLmFwcGVuZCh2bUluc3RhbGwuZ2V0TmFtZSgpKSwKCQkJCQkJCQkJCUlSdW50aW1lQ2xhc3NwYXRoRW50cnkuQk9PVFNUUkFQX0NMQVNTRVMpCgkJCQkJCQkJLmdldE1lbWVudG8oKSk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCX0KCgkJCUlQYXRoIGpyZVBhdGggPSBuZXcgUGF0aCh2bUluc3RhbGwuZ2V0SW5zdGFsbExvY2F0aW9uKCkKCQkJCQkuZ2V0QWJzb2x1dGVQYXRoKCkpOwoJCQlpZiAoanJlUGF0aCAhPSBudWxsKSB7CgkJCQlJUGF0aCB0b29sc1BhdGggPSBqcmVQYXRoLmFwcGVuZCgibGliIikuYXBwZW5kKCJ0b29scy5qYXIiKTsKCQkJCWlmICh0b29sc1BhdGgudG9GaWxlKCkuZXhpc3RzKCkpIHsKCQkJCQl0cnkgewoJCQkJCQljcC5hZGQoSmF2YVJ1bnRpbWUubmV3QXJjaGl2ZVJ1bnRpbWVDbGFzc3BhdGhFbnRyeSgKCQkJCQkJCQl0b29sc1BhdGgpLmdldE1lbWVudG8oKSk7CgkJCQkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlMSkgewoJCQkJCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNhdGNoIGJsb2NrCgkJCQkJCWUxLnByaW50U3RhY2tUcmFjZSgpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJd2Muc2V0QXR0cmlidXRlKAoJCQkJSUphdmFMYXVuY2hDb25maWd1cmF0aW9uQ29uc3RhbnRzLkFUVFJfQ0xBU1NQQVRILCBjcCk7CgkJd2Muc2V0QXR0cmlidXRlKAoJCQkJCQlJSmF2YUxhdW5jaENvbmZpZ3VyYXRpb25Db25zdGFudHMuQVRUUl9ERUZBVUxUX0NMQVNTUEFUSCwKCQkJCQkJZmFsc2UpOwoJfQoKCS8qKgoJICogVGVybWluYXRlcyB0aGUgc2VydmVyLgoJICovCglwdWJsaWMgdm9pZCB0ZXJtaW5hdGUoKSB7CgkJaWYgKGZMaXZlU2VydmVyLmdldFNlcnZlclN0YXRlKCkgPT0gSVNlcnZlci5TRVJWRVJfU1RPUFBFRCkKCQkJcmV0dXJuOwoKCQl0cnkgewoJCQlmTGl2ZVNlcnZlci5zZXRTZXJ2ZXJTdGF0ZShJU2VydmVyLlNFUlZFUl9TVE9QUElORyk7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIktpbGxpbmcgdGhlIFNlcnZlciBwcm9jZXNzIik7CgkJCWlmIChwcm9jZXNzICE9IG51bGwgJiYgIXByb2Nlc3MuaXNUZXJtaW5hdGVkKCkpIHsKCQkJCXByb2Nlc3MudGVybWluYXRlKCk7CgkJCQlzdG9wSW1wbCgpOwoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3Iga2lsbGluZyB0aGUgcHJvY2VzcyIsIGUpOwoJCX0KCX0KCQoJcHJvdGVjdGVkIHZvaWQgc3RvcEltcGwoKSB7CgkJaWYgKHBpbmcgIT0gbnVsbCkgewoJCQlwaW5nLnN0b3BQaW5naW5nKCk7CgkJCXBpbmcgPSBudWxsOwoJCX0KCQlpZiAocHJvY2VzcyAhPSBudWxsKSB7CgkJCXByb2Nlc3MgPSBudWxsOwoJCQlEZWJ1Z1BsdWdpbi5nZXREZWZhdWx0KCkucmVtb3ZlRGVidWdFdmVudExpc3RlbmVyKHByb2Nlc3NMaXN0ZW5lcik7CgkJCXByb2Nlc3NMaXN0ZW5lciA9IG51bGw7CgkJfQoJCWZMaXZlU2VydmVyLnNldFNlcnZlclN0YXRlKElTZXJ2ZXIuU0VSVkVSX1NUT1BQRUQpOwoJfQkKCXB1YmxpYyB2b2lkIHNldFByb2Nlc3MoZmluYWwgSVByb2Nlc3MgbmV3UHJvY2VzcykgewoJCWlmIChwcm9jZXNzICE9IG51bGwpCgkJCXJldHVybjsKCgkJcHJvY2VzcyA9IG5ld1Byb2Nlc3M7CgkJcHJvY2Vzc0xpc3RlbmVyID0gbmV3IElEZWJ1Z0V2ZW50U2V0TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIGhhbmRsZURlYnVnRXZlbnRzKERlYnVnRXZlbnRbXSBldmVudHMpIHsKCQkJCWlmIChldmVudHMgIT0gbnVsbCkgewoJCQkJCWludCBzaXplID0gZXZlbnRzLmxlbmd0aDsKCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCQlpZiAocHJvY2Vzcy5lcXVhbHMoZXZlbnRzW2ldLmdldFNvdXJjZSgpKSAmJiBldmVudHNbaV0uZ2V0S2luZCgpID09IERlYnVnRXZlbnQuVEVSTUlOQVRFKSB7CgkJCQkJCQlEZWJ1Z1BsdWdpbi5nZXREZWZhdWx0KCkucmVtb3ZlRGVidWdFdmVudExpc3RlbmVyKHRoaXMpOwoJCQkJCQkJc3RvcEltcGwoKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX07CgkJRGVidWdQbHVnaW4uZ2V0RGVmYXVsdCgpLmFkZERlYnVnRXZlbnRMaXN0ZW5lcihwcm9jZXNzTGlzdGVuZXIpOwoJfQoJCglwdWJsaWMgaW50IGdldFN0YXJ0VGltZW91dCgpIHsKCQlyZXR1cm4gMzAwMDAwOwoJfQoJCglwdWJsaWMgaW50IGdldFN0b3BUaW1lb3V0KCkgewoJCXJldHVybiAzMDAwMDA7Cgl9CgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLnd0cC5zZXJ2ZXIuY29yZS5tb2RlbC5JVVJMUHJvdmlkZXIjZ2V0TW9kdWxlUm9vdFVSTChvcmcuZWNsaXBzZS53dHAuc2VydmVyLmNvcmUubW9kZWwuSU1vZHVsZSkKCSAqLwoJcHVibGljIFVSTCBnZXRNb2R1bGVSb290VVJMKElNb2R1bGUgbW9kdWxlKSB7CgoJCXRyeSB7CgkJCWlmIChtb2R1bGUgPT0gbnVsbCB8fCAhKG1vZHVsZSBpbnN0YW5jZW9mIElXZWJNb2R1bGUpKQoJCQkJcmV0dXJuIG51bGw7CgoJCQlJU2VydmVyQ29uZmlndXJhdGlvbiBzZXJ2ZXJDb25maWcgPSBmTGl2ZVNlcnZlcgoJCQkJCS5nZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCk7CgkJCWlmIChzZXJ2ZXJDb25maWcgPT0gbnVsbCkKCQkJCXJldHVybiBudWxsOwoKCQkJU3RyaW5nIHVybCA9ICJodHRwOi8vbG9jYWxob3N0IjsKCQkJaW50IHBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRQb3J0KCkpOwoJCQlwb3J0ID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJNb25pdG9yTWFuYWdlcigpLmdldE1vbml0b3JlZFBvcnQoCgkJCQkJZkxpdmVTZXJ2ZXIsIHBvcnQsICJ3ZWIiKTsKCQkJaWYgKHBvcnQgIT0gODApCgkJCQl1cmwgKz0gIjoiICsgcG9ydDsKCgkJCXVybCArPSAiLyIrbW9kdWxlLmdldE5hbWUoKTsKCgkJCWlmICghdXJsLmVuZHNXaXRoKCIvIikpCgkJCQl1cmwgKz0gIi8iOwoKCQkJcmV0dXJuIG5ldyBVUkwodXJsKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZSgiQ291bGQgbm90IGdldCByb290IFVSTCIsIGUpOwoJCQlyZXR1cm4gbnVsbDsKCQl9CgoJfQoKfQ==