cGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMgSUJNIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIKAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUHJvamVjdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLlJlc291cmNlc1BsdWdpbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLk51bGxQcm9ncmVzc01vbml0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLkRpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuTWVzc2FnZURpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuUHJvZ3Jlc3NNb25pdG9yRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UucHJlZmVyZW5jZS5QcmVmZXJlbmNlUGFnZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVN0cnVjdHVyZWRTZWxlY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS53aW5kb3cuV2luZG93OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LlNXVDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29udHJvbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklXb3JrYmVuY2hQcmVmZXJlbmNlUGFnZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmhlbHAuV29ya2JlbmNoSGVscDsKCmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JUnVudGltZUxvY2F0b3JMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuU2VydmVyVUlDb3JlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC50YXNrLkZpbmlzaFdpemFyZEZyYWdtZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC50YXNrLlNhdmVSdW50aW1lVGFzazsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwudmlld2Vycy5SdW50aW1lQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC53aXphcmQuQ2xvc2FibGVXaXphcmREaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLndpemFyZC5mcmFnbWVudC5OZXdSdW50aW1lV2l6YXJkRnJhZ21lbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLndpemFyZC5JV2l6YXJkRnJhZ21lbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLndpemFyZC5UYXNrV2l6YXJkOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS53aXphcmQuV2l6YXJkRnJhZ21lbnQ7Ci8qKgogKiBUaGUgcHJlZmVyZW5jZSBwYWdlIHRoYXQgaG9sZHMgc2VydmVyIHJ1bnRpbWVzLgogKi8KcHVibGljIGNsYXNzIFJ1bnRpbWVQcmVmZXJlbmNlUGFnZSBleHRlbmRzIFByZWZlcmVuY2VQYWdlIGltcGxlbWVudHMgSVdvcmtiZW5jaFByZWZlcmVuY2VQYWdlIHsKCXByb3RlY3RlZCBCdXR0b24gZWRpdDsKCXByb3RlY3RlZCBCdXR0b24gcmVtb3ZlOwoKCS8qKgoJICogUnVudGltZVByZWZlcmVuY2VzUGFnZSBjb25zdHJ1Y3RvciBjb21tZW50LgoJICovCglwdWJsaWMgUnVudGltZVByZWZlcmVuY2VQYWdlKCkgewoJCXN1cGVyKCk7CgkJbm9EZWZhdWx0QW5kQXBwbHlCdXR0b24oKTsKCX0KCQoJLyoqCgkgKiBDcmVhdGUgdGhlIHByZWZlcmVuY2Ugb3B0aW9ucy4KCSAqCgkgKiBAcGFyYW0gcGFyZW50IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZQoJICogQHJldHVybiBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db250cm9sCgkgKi8KCXByb3RlY3RlZCBDb250cm9sIGNyZWF0ZUNvbnRlbnRzKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlpbml0aWFsaXplRGlhbG9nVW5pdHMocGFyZW50KTsKCQkKCQlDb21wb3NpdGUgY29tcG9zaXRlID0gbmV3IENvbXBvc2l0ZShwYXJlbnQsIFNXVC5OT05FKTsKCQlHcmlkTGF5b3V0IGxheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJbGF5b3V0Lmhvcml6b250YWxTcGFjaW5nID0gY29udmVydEhvcml6b250YWxETFVzVG9QaXhlbHMoNCk7CgkJbGF5b3V0LnZlcnRpY2FsU3BhY2luZyA9IGNvbnZlcnRWZXJ0aWNhbERMVXNUb1BpeGVscyg0KTsKCQlsYXlvdXQubWFyZ2luV2lkdGggPSAwOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSAwOwoJCWxheW91dC5udW1Db2x1bW5zID0gMjsKCQljb21wb3NpdGUuc2V0TGF5b3V0KGxheW91dCk7CgkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKTsKCQljb21wb3NpdGUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlXb3JrYmVuY2hIZWxwLnNldEhlbHAoY29tcG9zaXRlLCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTCk7CgkJCgkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoY29tcG9zaXRlLCBTV1QuV1JBUCk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCWxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgkJbGFiZWwuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXByZWZlcmVuY2VSdW50aW1lc0Rlc2NyaXB0aW9uIikpOwoJCQoJCWZpbmFsIFJ1bnRpbWVDb21wb3NpdGUgcnVudGltZUNvbXAgPSBuZXcgUnVudGltZUNvbXBvc2l0ZShjb21wb3NpdGUsIFNXVC5OT05FLCBuZXcgUnVudGltZUNvbXBvc2l0ZS5SdW50aW1lU2VsZWN0aW9uTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHJ1bnRpbWVTZWxlY3RlZChJUnVudGltZSBydW50aW1lKSB7CgkJCQlpZiAocnVudGltZSA9PSBudWxsIHx8IHJ1bnRpbWUuaXNMb2NrZWQoKSkgewoJCQkJCWVkaXQuc2V0RW5hYmxlZChmYWxzZSk7CgkJCQkJcmVtb3ZlLnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJfSBlbHNlIHsKCQkJCQllZGl0LnNldEVuYWJsZWQodHJ1ZSk7CgkJCQkJcmVtb3ZlLnNldEVuYWJsZWQodHJ1ZSk7CgkJCQl9CgkJCX0KCQl9KTsKCQlydW50aW1lQ29tcC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwgfCBHcmlkRGF0YS5GSUxMX1ZFUlRJQ0FMKSk7CgkJCgkJQ29tcG9zaXRlIGJ1dHRvbkNvbXAgPSBuZXcgQ29tcG9zaXRlKGNvbXBvc2l0ZSwgU1dULk5PTkUpOwoJCWxheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJbGF5b3V0Lmhvcml6b250YWxTcGFjaW5nID0gMDsKCQlsYXlvdXQudmVydGljYWxTcGFjaW5nID0gY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKDQpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7CgkJbGF5b3V0Lm51bUNvbHVtbnMgPSAxOwoJCWJ1dHRvbkNvbXAuc2V0TGF5b3V0KGxheW91dCk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKTsKCQlidXR0b25Db21wLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJQnV0dG9uIGFkZCA9IFNXVFV0aWwuY3JlYXRlQnV0dG9uKGJ1dHRvbkNvbXAsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWRkIikpOwoJCWFkZC5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaWYgKHNob3dXaXphcmQobnVsbCkgPT0gV2luZG93LkNBTkNFTCkKCQkJCQlyZXR1cm47CgkJCQlydW50aW1lQ29tcC5yZWZyZXNoKCk7CgkJCX0KCQl9KTsKCQkKCQllZGl0ID0gU1dUVXRpbC5jcmVhdGVCdXR0b24oYnV0dG9uQ29tcCwgU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlZGl0IikpOwoJCWVkaXQuc2V0RW5hYmxlZChmYWxzZSk7CgkJZWRpdC5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJSVJ1bnRpbWUgcnVudGltZSA9IHJ1bnRpbWVDb21wLmdldFNlbGVjdGVkUnVudGltZSgpOwoJCQkJaWYgKHJ1bnRpbWUgIT0gbnVsbCkgewoJCQkJCUlSdW50aW1lV29ya2luZ0NvcHkgcnVudGltZVdvcmtpbmdDb3B5ID0gcnVudGltZS5nZXRXb3JraW5nQ29weSgpOwoJCQkJCWlmIChzaG93V2l6YXJkKHJ1bnRpbWVXb3JraW5nQ29weSkgIT0gV2luZG93LkNBTkNFTCkgewoJCQkJCQl0cnkgewoJCQkJCQkJcnVudGltZVdvcmtpbmdDb3B5LnNhdmUobmV3IE51bGxQcm9ncmVzc01vbml0b3IoKSk7CgkJCQkJCQlydW50aW1lQ29tcC5yZWZyZXNoKHJ1bnRpbWUpOwoJCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsgfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0pOwoJCQoJCXJlbW92ZSA9IFNXVFV0aWwuY3JlYXRlQnV0dG9uKGJ1dHRvbkNvbXAsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcmVtb3ZlIikpOwoJCXJlbW92ZS5zZXRFbmFibGVkKGZhbHNlKTsKCQlyZW1vdmUuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCUlSdW50aW1lIHJ1bnRpbWUgPSBydW50aW1lQ29tcC5nZXRTZWxlY3RlZFJ1bnRpbWUoKTsKCQkJCWlmIChzaG91bGRSZW1vdmVSdW50aW1lKHJ1bnRpbWUpKQoJCQkJCXRyeSB7CgkJCQkJCXJ1bnRpbWUuZGVsZXRlKCk7CgkJCQkJCXJ1bnRpbWVDb21wLnJlbW92ZShydW50aW1lKTsKCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsgfQoJCQl9CgkJfSk7CgkJCgkJQnV0dG9uIHNlYXJjaCA9IFNXVFV0aWwuY3JlYXRlQnV0dG9uKGJ1dHRvbkNvbXAsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlc2VhcmNoIikpOwoJCXNlYXJjaC5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJdHJ5IHsKCQkJCQlQcm9ncmVzc01vbml0b3JEaWFsb2cgZGlhbG9nID0gbmV3IFByb2dyZXNzTW9uaXRvckRpYWxvZyhnZXRTaGVsbCgpKTsKCQkJCQlkaWFsb2cuc2V0QmxvY2tPbk9wZW4oZmFsc2UpOwoJCQkJCWRpYWxvZy5vcGVuKCk7CgkJCQkJZmluYWwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yID0gZGlhbG9nLmdldFByb2dyZXNzTW9uaXRvcigpOwoJCQkJCWZpbmFsIExpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQkJCQkKCQkJCQlJUnVudGltZUxvY2F0b3JMaXN0ZW5lciBsaXN0ZW5lciA9IG5ldyBJUnVudGltZUxvY2F0b3JMaXN0ZW5lcigpIHsKCQkJCQkJcHVibGljIHZvaWQgcnVudGltZUZvdW5kKElSdW50aW1lIHJ1bnRpbWUpIHsKCQkJCQkJCW1vbml0b3Iuc3ViVGFzayhydW50aW1lLmdldE5hbWUoKSk7CgkJCQkJCQlsaXN0LmFkZChydW50aW1lKTsKCQkJCQkJfQoJCQkJCX07CgkJCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBTZXJ2ZXJDb3JlLmdldFJ1bnRpbWVMb2NhdG9ycygpLml0ZXJhdG9yKCk7CgkJCQkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQkJCQlJUnVudGltZUxvY2F0b3IgbG9jYXRvciA9IChJUnVudGltZUxvY2F0b3IpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCQkJbG9jYXRvci5zZWFyY2hGb3JSdW50aW1lcyhsaXN0ZW5lciwgbW9uaXRvcik7CgkJCQkJfQoJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVSLCAiRm91bmQgcnVudGltZXM6ICIgKyBsaXN0LnNpemUoKSk7CgkJCQkJCgkJCQkJLy8gcmVtb3ZlIGR1cGxpY2F0ZXMgZnJvbSBsaXN0IChiYXNlZCBvbiBsb2NhdGlvbikKCQkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FUiwgIlJlbW92aW5nIGR1cGxpY2F0ZXMiKTsKCQkJCQlMaXN0IGdvb2QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCQkJSXRlcmF0b3IgaXRlcmF0b3IyID0gbGlzdC5pdGVyYXRvcigpOwoJCQkJCXdoaWxlIChpdGVyYXRvcjIuaGFzTmV4dCgpKSB7CgkJCQkJCWJvb2xlYW4gZHVwID0gZmFsc2U7CgkJCQkJCUlSdW50aW1lIHdjID0gKElSdW50aW1lKSBpdGVyYXRvcjIubmV4dCgpOwoJCQkJCQkKCQkJCQkJaXRlcmF0b3IgPSBTZXJ2ZXJDb3JlLmdldFJlc291cmNlTWFuYWdlcigpLmdldFJ1bnRpbWVzKCkuaXRlcmF0b3IoKTsKCQkJCQkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQkJCQkJSVJ1bnRpbWUgcnVudGltZSA9IChJUnVudGltZSkgaXRlcmF0b3IubmV4dCgpOwoJCQkJCQkJaWYgKHJ1bnRpbWUuZ2V0TG9jYXRpb24oKS5lcXVhbHMod2MuZ2V0TG9jYXRpb24oKSkpCgkJCQkJCQkJZHVwID0gdHJ1ZTsKCQkJCQkJfQoJCQkJCQlpZiAoIWR1cCkKCQkJCQkJCWdvb2QuYWRkKHdjKTsKCQkJCQl9CgkJCQkJCgkJCQkJLy8gYWRkIHRvIGxpc3QKCQkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FUiwgIkFkZGluZyBydW50aW1lczogIiArIGdvb2Quc2l6ZSgpKTsKCQkJCQlpdGVyYXRvciA9IGdvb2QuaXRlcmF0b3IoKTsKCQkJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQkJCUlSdW50aW1lV29ya2luZ0NvcHkgd2MgPSAoSVJ1bnRpbWVXb3JraW5nQ29weSkgaXRlcmF0b3IubmV4dCgpOwoJCQkJCQl3Yy5zYXZlKG1vbml0b3IpOwoJCQkJCX0KCQkJCQlkaWFsb2cuY2xvc2UoKTsKCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewoJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGZpbmRpbmcgcnVudGltZXMiLCBleCk7CgkJCQl9CgkJCQlydW50aW1lQ29tcC5yZWZyZXNoKCk7CgkJCX0KCQl9KTsKCQkKCQlEaWFsb2cuYXBwbHlEaWFsb2dGb250KGNvbXBvc2l0ZSk7CgkKCQlyZXR1cm4gY29tcG9zaXRlOwoJfQoJCglwcm90ZWN0ZWQgYm9vbGVhbiBzaG91bGRSZW1vdmVSdW50aW1lKElSdW50aW1lIHJ1bnRpbWUpIHsKCQlpZiAocnVudGltZSA9PSBudWxsKQoJCQlyZXR1cm4gZmFsc2U7CgoJCS8vIGNoZWNrIGZvciB1c2UKCQlib29sZWFuIGluVXNlID0gZmFsc2U7CgkKCQlJdGVyYXRvciBpdGVyYXRvciA9IFNlcnZlckNvcmUuZ2V0UmVzb3VyY2VNYW5hZ2VyKCkuZ2V0U2VydmVycygpLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlJU2VydmVyIHNlcnZlciA9IChJU2VydmVyKSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmIChydW50aW1lLmVxdWFscyhzZXJ2ZXIuZ2V0UnVudGltZSgpKSkKCQkJCWluVXNlID0gdHJ1ZTsKCQl9CgkJCgkJSVByb2plY3RbXSBwcm9qZWN0cyA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCkuZ2V0UHJvamVjdHMoKTsKCQlpZiAocHJvamVjdHMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHByb2plY3RzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlQcm9qZWN0UHJvcGVydGllcyBwcm9wcyA9IFNlcnZlckNvcmUuZ2V0UHJvamVjdFByb3BlcnRpZXMocHJvamVjdHNbaV0pOwoJCQkJaWYgKHJ1bnRpbWUuZXF1YWxzKHByb3BzLmdldFJ1bnRpbWVUYXJnZXQoKSkpCgkJCQkJaW5Vc2UgPSB0cnVlOwoJCQl9CgkJfQoJCQoJCWlmIChpblVzZSkgewoJCQlpZiAoIU1lc3NhZ2VEaWFsb2cub3BlbkNvbmZpcm0oZ2V0U2hlbGwoKSwgU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkZWZhdWx0RGlhbG9nVGl0bGUiKSwgU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkaWFsb2dSdW50aW1lSW5Vc2UiKSkpCgkJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCQoJCXJldHVybiB0cnVlOwoJfQoJCglwcm90ZWN0ZWQgaW50IHNob3dXaXphcmQoZmluYWwgSVJ1bnRpbWVXb3JraW5nQ29weSBydW50aW1lV29ya2luZ0NvcHkpIHsKCQlTdHJpbmcgdGl0bGUgPSBudWxsOwoJCUlXaXphcmRGcmFnbWVudCBmcmFnbWVudCA9IG51bGw7CgkJaWYgKHJ1bnRpbWVXb3JraW5nQ29weSA9PSBudWxsKSB7CgkJCXRpdGxlID0gU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpOZXdSdW50aW1lV2l6YXJkVGl0bGUiKTsKCQkJZnJhZ21lbnQgPSBuZXcgV2l6YXJkRnJhZ21lbnQoKSB7CgkJCQlwdWJsaWMgdm9pZCBjcmVhdGVTdWJGcmFnbWVudHMoTGlzdCBsaXN0KSB7CgkJCQkJbGlzdC5hZGQobmV3IE5ld1J1bnRpbWVXaXphcmRGcmFnbWVudCgpKTsKCQkJCQlsaXN0LmFkZChuZXcgRmluaXNoV2l6YXJkRnJhZ21lbnQobmV3IFNhdmVSdW50aW1lVGFzaygpKSk7CgkJCQl9CgkJCX07CgkJfSBlbHNlIHsKCQkJdGl0bGUgPSBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpekVkaXRSdW50aW1lV2l6YXJkVGl0bGUiKTsKCQkJZmluYWwgSVdpemFyZEZyYWdtZW50IGZyYWdtZW50MiA9IFNlcnZlclVJQ29yZS5nZXRXaXphcmRGcmFnbWVudChydW50aW1lV29ya2luZ0NvcHkuZ2V0UnVudGltZVR5cGUoKS5nZXRJZCgpKTsKCQkJaWYgKGZyYWdtZW50MiA9PSBudWxsKSB7CgkJCQllZGl0LnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJcmV0dXJuIFdpbmRvdy5DQU5DRUw7CgkJCX0KCQkJZnJhZ21lbnQgPSBuZXcgV2l6YXJkRnJhZ21lbnQoKSB7CgkJCQlwdWJsaWMgdm9pZCBjcmVhdGVTdWJGcmFnbWVudHMoTGlzdCBsaXN0KSB7CgkJCQkJbGlzdC5hZGQobmV3IFdpemFyZEZyYWdtZW50KCkgewoJCQkJCQlwdWJsaWMgdm9pZCBlbnRlcigpIHsKCQkJCQkJCWdldFRhc2tNb2RlbCgpLnB1dE9iamVjdChJVGFza01vZGVsLlRBU0tfUlVOVElNRSwgcnVudGltZVdvcmtpbmdDb3B5KTsKCQkJCQkJfQoJCQkJCX0pOwoJCQkJCWxpc3QuYWRkKGZyYWdtZW50Mik7CgkJCQkJbGlzdC5hZGQobmV3IEZpbmlzaFdpemFyZEZyYWdtZW50KG5ldyBTYXZlUnVudGltZVRhc2soKSkpOwoJCQkJfQoJCQl9OwoJCX0KCQlUYXNrV2l6YXJkIHdpemFyZCA9IG5ldyBUYXNrV2l6YXJkKHRpdGxlLCBmcmFnbWVudCk7CgkJd2l6YXJkLnNldEZvcmNlUHJldmlvdXNBbmROZXh0QnV0dG9ucyh0cnVlKTsKCQlDbG9zYWJsZVdpemFyZERpYWxvZyBkaWFsb2cgPSBuZXcgQ2xvc2FibGVXaXphcmREaWFsb2coZ2V0U2hlbGwoKSwgd2l6YXJkKTsKCQlyZXR1cm4gZGlhbG9nLm9wZW4oKTsKCX0KCQoJcHJvdGVjdGVkIElSdW50aW1lIGdldFNlbGVjdGlvbihJU2VsZWN0aW9uIHNlbDIpIHsKCQlJU3RydWN0dXJlZFNlbGVjdGlvbiBzZWwgPSAoSVN0cnVjdHVyZWRTZWxlY3Rpb24pIHNlbDI7CgkJcmV0dXJuIChJUnVudGltZSkgc2VsLmdldEZpcnN0RWxlbWVudCgpOwoJfQoJCgkvKioKCSAqIEluaXRpYWxpemVzIHRoaXMgcHJlZmVyZW5jZSBwYWdlIHVzaW5nIHRoZSBwYXNzZWQgZGVza3RvcC4KCSAqCgkgKiBAcGFyYW0gZGVza3RvcCB0aGUgY3VycmVudCBkZXNrdG9wCgkgKi8KCXB1YmxpYyB2b2lkIGluaXQoSVdvcmtiZW5jaCB3b3JrYmVuY2gpIHsgfQoKCS8qKgoJICogUGVyZm9ybXMgc3BlY2lhbCBwcm9jZXNzaW5nIHdoZW4gdGhpcyBwYWdlJ3MgRGVmYXVsdHMgYnV0dG9uIGhhcyBiZWVuIHByZXNzZWQuCgkgKiA8cD4KCSAqIFRoaXMgaXMgYSBmcmFtZXdvcmsgaG9vayBtZXRob2QgZm9yIHN1YmxjYXNzZXMgdG8gZG8gc3BlY2lhbCB0aGluZ3Mgd2hlbgoJICogdGhlIERlZmF1bHRzIGJ1dHRvbiBoYXMgYmVlbiBwcmVzc2VkLgoJICogU3ViY2xhc3NlcyBtYXkgb3ZlcnJpZGUsIGJ1dCBzaG91bGQgY2FsbCA8Y29kZT5zdXBlci5wZXJmb3JtRGVmYXVsdHM8L2NvZGU+LgoJICogPC9wPgoJICovCglwcm90ZWN0ZWQgdm9pZCBwZXJmb3JtRGVmYXVsdHMoKSB7CgkJc3VwZXIucGVyZm9ybURlZmF1bHRzKCk7Cgl9CgoJLyoqIAoJICogTWV0aG9kIGRlY2xhcmVkIG9uIElQcmVmZXJlbmNlUGFnZS4KCSAqIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlCgkgKi8KCXB1YmxpYyBib29sZWFuIHBlcmZvcm1PaygpIHsKCQkvLyBUT0RPIC0gc2hvdWxkIG5vdCBzYXZlIHVudGlsIHVzZXIgaGl0cyBvayAKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXRWaXNpYmxlKGJvb2xlYW4gdmlzaWJsZSkgewoJCXN1cGVyLnNldFZpc2libGUodmlzaWJsZSk7CgkJaWYgKHZpc2libGUpCgkJCXNldFRpdGxlKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZmVyZW5jZVJ1bnRpbWVzVGl0bGVMb25nIikpOwoJfQp9