LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBHb3JrZW0gRXJjYW4gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE5hY2kgTS4gRGFpCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVBBQ0hFIFNPRlRXQVJFIEZPVU5EQVRJT04gT1IKICogSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCiAqIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAogKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwKICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUCiAqIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKICogaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBFdGVyYXRpb24gQmlsaXNpbSBBLlMuICBGb3IgbW9yZQogKiBpbmZvcm1hdGlvbiBvbiBldGVyYXRpb24sIHBsZWFzZSBzZWUKICogPGh0dHA6Ly93d3cuZXRlcmF0aW9uLmNvbS8+LgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuZ2VuZXJpYy5pbnRlcm5hbC51aTsKCmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuTnVsbFByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuSU1lc3NhZ2VQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuZ2VuZXJpYy5pbnRlcm5hbC5jb3JlLkdlbmVyaWNTZXJ2ZXJSdW50aW1lOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLnNlcnZlcnR5cGUuZGVmaW5pdGlvbi5TZXJ2ZXJSdW50aW1lOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLnVpLkdlbmVyaWNTZXJ2ZXJVSU1lc3NhZ2VzOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LlNXVDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbWJvOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuR3JvdXA7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JUnVudGltZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JUnVudGltZVR5cGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVJ1bnRpbWVXb3JraW5nQ29weTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JVGFza01vZGVsOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLlNlcnZlckNvcmU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuUnVudGltZURlbGVnYXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS53aXphcmQuSVdpemFyZEhhbmRsZTsKCi8qKgogKiBBIHNlcnZlckRlZmluaXRpb25UeXBlIGF3YXJlIHdpemFyZCBmb3IgZGVmaW5pbmcgcnVudGltZXMuCiAqIAogKiBAYXV0aG9yIEdvcmtlbSBFcmNhbgogKi8KcHVibGljIGNsYXNzIEdlbmVyaWNTZXJ2ZXJSdW50aW1lV2l6YXJkRnJhZ21lbnQgZXh0ZW5kcyBTZXJ2ZXJEZWZpbml0aW9uVHlwZUF3YXJlV2l6YXJkRnJhZ21lbnQgewoJCgoJcHJpdmF0ZSBHcm91cCBzZWxlY3Rpb25CYXI7Cglwcml2YXRlIENvbWJvIGZTZXJ2ZXJDb21ibzsKCXByaXZhdGUgU2VydmVyVHlwZURlZmluaXRpb25Hcm91cCBmU2VydmVyUGFuZWw7Cglwcml2YXRlIFJ1bnRpbWVEZWxlZ2F0ZSBmUnVudGltZURlbGVnYXRlOwogICAgcHJpdmF0ZSBNYXAgZlNlcnZlclJ1bnRpbWVQcm9wZXJ0aWVzOwogICAgcHJpdmF0ZSBTdHJpbmcgZlNlbGVjdGVkU2VydmVyVHlwZTsKICAgIAoJCgkvKioKCSAqIENvbnN0cnVjdG9yCgkgKi8KCXB1YmxpYyBHZW5lcmljU2VydmVyUnVudGltZVdpemFyZEZyYWdtZW50KCkgewoJCXN1cGVyKCk7Cgl9CgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIGNvbS5pYm0ud3RwLnNlcnZlci51aS53aXphcmQuSVdpemFyZEZyYWdtZW50I2lzQ29tcGxldGUoKQoJICovCglwdWJsaWMgYm9vbGVhbiBpc0NvbXBsZXRlKCkgewoJICAJUnVudGltZURlbGVnYXRlIHJ1bnRpbWUgPSBnZXRSdW50aW1lRGVsZWdhdGUoKTsKCQlpZiAocnVudGltZSA9PSBudWxsKQoJCQlyZXR1cm4gZmFsc2U7CgkJSVN0YXR1cyBzdGF0dXMgPSBydW50aW1lLnZhbGlkYXRlKCk7CgkJcmV0dXJuIChzdGF0dXMgIT0gbnVsbCAmJiBzdGF0dXMuaXNPSygpKTsKCX0KCQoJcHVibGljIHZvaWQgY3JlYXRlQ29udGVudChDb21wb3NpdGUgcGFyZW50LCBJV2l6YXJkSGFuZGxlIGhhbmRsZSkgewoJCWZSdW50aW1lRGVsZWdhdGU9bnVsbDsKCQljcmVhdGVTZWxlY3Rpb25CYXIocGFyZW50KTsKCQljcmVhdGVTZXJ2ZXJEZWZpbml0aW9uVHlwZUNvbXBvc2l0ZShwYXJlbnQpOwoJfQoKCQoJcHJpdmF0ZSB2b2lkIHN3YXBCb2R5KCkgCgl7CgkgICAgdGhpcy5mUnVudGltZURlbGVnYXRlPW51bGw7CiAgICAgICAgU3RyaW5nIHNlbGVjdGVkID0gZlNlcnZlckNvbWJvID09IG51bGwgPyBudWxsIDogZlNlcnZlckNvbWJvCiAgICAgICAgICAgICAgICAuZ2V0SXRlbShmU2VydmVyQ29tYm8uZ2V0U2VsZWN0aW9uSW5kZXgoKSk7CiAgICAgICAgTWFwIHByb3BlcnRpZXMgPSBudWxsOwogICAgICAgIFNlcnZlclJ1bnRpbWUgZGVmaW5pdGlvbiA9IGdldFNlcnZlclR5cGVEZWZpbml0aW9uKHNlbGVjdGVkLHByb3BlcnRpZXMpOwogICAgICAgIGZTZXJ2ZXJQYW5lbC5yZXNldChkZWZpbml0aW9uLFNlcnZlclR5cGVEZWZpbml0aW9uR3JvdXAuQ09OVEVYVF9SVU5USU1FLCBwcm9wZXJ0aWVzKTsKICAgIH0KCS8qKgogICAgICogQHBhcmFtIHNlbGVjdGVkCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBjcmVhdGVTZXJ2ZXJEZWZpbml0aW9uVHlwZUNvbXBvc2l0ZShDb21wb3NpdGUgcGFyZW50KSB7ICAgICAKICAgICAgICBTdHJpbmcgc2VsZWN0ZWQgPSBmU2VydmVyQ29tYm89PW51bGw/bnVsbDpmU2VydmVyQ29tYm8uZ2V0SXRlbShmU2VydmVyQ29tYm8uZ2V0U2VsZWN0aW9uSW5kZXgoKSk7CiAgICAgICAgaWYoZ2V0U2VydmVyRGVmaW5pdGlvbklkKCkhPW51bGwpCgkJICAgIHNlbGVjdGVkPWdldFNlcnZlckRlZmluaXRpb25JZCgpOwogICAgICAgIE1hcCBwcm9wZXJ0aWVzPSBudWxsOwogICAgICAgIGlmKGdldFJ1bnRpbWVEZWxlZ2F0ZSgpIT1udWxsKQogICAgICAgICAgICBwcm9wZXJ0aWVzID0gZ2V0UnVudGltZURlbGVnYXRlKCkuZ2V0QXR0cmlidXRlKEdlbmVyaWNTZXJ2ZXJSdW50aW1lLlNFUlZFUl9JTlNUQU5DRV9QUk9QRVJUSUVTLChNYXApbnVsbCk7CiAgICAgICAgU2VydmVyUnVudGltZSBkZWZpbml0aW9uID0gZ2V0U2VydmVyVHlwZURlZmluaXRpb24oc2VsZWN0ZWQscHJvcGVydGllcyk7CiAgICAgICAgZlNlcnZlclBhbmVsID0gbmV3IFNlcnZlclR5cGVEZWZpbml0aW9uR3JvdXAodGhpcyxkZWZpbml0aW9uLFNlcnZlclR5cGVEZWZpbml0aW9uR3JvdXAuQ09OVEVYVF9SVU5USU1FLHByb3BlcnRpZXMscGFyZW50KTsKICAgIH0KICAgIHByaXZhdGUgdm9pZCBjcmVhdGVTZWxlY3Rpb25CYXIoQ29tcG9zaXRlIGNvbnRlbnQpIHsKCQlzZWxlY3Rpb25CYXIgPSBuZXcgR3JvdXAoY29udGVudCwgU1dULlNIQURPV19FVENIRURfSU4pOwoJCXNlbGVjdGlvbkJhci5zZXRMYXlvdXQobmV3IEdyaWRMYXlvdXQoMixmYWxzZSkpOwoJCXNlbGVjdGlvbkJhci5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChzZWxlY3Rpb25CYXIsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KEdlbmVyaWNTZXJ2ZXJVSU1lc3NhZ2VzLmdldFN0cmluZygicnVudGltZVdpemFyZC5sYWJlbC5zZXJ2ZXJUeXBlIikpOwoJCWxhYmVsLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKCkpOwoJCWZTZXJ2ZXJDb21ibyA9IG5ldyBDb21ibyhzZWxlY3Rpb25CYXIsIFNXVC5CT1JERVIgfFNXVC5SRUFEX09OTFkpOwoJCVNlcnZlclJ1bnRpbWVbXSBzZXJ2ZXJzID0gZ2V0QWxsU2VydmVyRGVmaW5pdGlvblR5cGVzKCk7CgkJZm9yKGludCBpPTA7IGk8c2VydmVycy5sZW5ndGg7IGkrKyl7CgkJCWZTZXJ2ZXJDb21iby5hZGQoc2VydmVyc1tpXS5nZXROYW1lKCkpOwoJCX0KCQlmU2VydmVyQ29tYm8uc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMIHwgR3JpZERhdGEuR1JBQl9IT1JJWk9OVEFMKSk7CgkJaWYoZlNlcnZlckNvbWJvLmdldEl0ZW1Db3VudCgpPjApCgkJewoJCSAgICBpZihnZXRTZXJ2ZXJEZWZpbml0aW9uSWQoKSE9bnVsbCkKCQkgICAgewoJCSAgICAgICAgc2VsZWN0U2VydmVyRGVmaW5pdGlvbigpOwoJCSAgICB9CgkJICAgIGZTZXJ2ZXJDb21iby5zZWxlY3QoMCk7CgkJfQoJCWZTZXJ2ZXJDb21iby5hZGRTZWxlY3Rpb25MaXN0ZW5lcigKCQkJCW5ldyBTZWxlY3Rpb25MaXN0ZW5lcigpIHsKCQkJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQkJCXN3YXBCb2R5KCk7CgkJCQkJCXNlcnZlckRlZmluaXRpb25UeXBlUHJvcGVydGllc0NoYW5nZWQoKTsKCQkJCQl9CgkJCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHt9CgkJCQl9CgkJCSk7Cgl9CgoJCglwcml2YXRlIFN0cmluZyBnZXRTZXJ2ZXJEZWZpbml0aW9uSWQoKQoJewoJCVN0cmluZyBjdXJyZW50RGVmaW5pdGlvbj0gbnVsbDsKCQlpZihnZXRSdW50aW1lRGVsZWdhdGUoKSE9bnVsbCkKCQkJY3VycmVudERlZmluaXRpb24gPSAgZ2V0UnVudGltZURlbGVnYXRlKCkuZ2V0QXR0cmlidXRlKEdlbmVyaWNTZXJ2ZXJSdW50aW1lLlNFUlZFUl9ERUZJTklUSU9OX0lELCIiKTsKCQlpZihjdXJyZW50RGVmaW5pdGlvbiE9IG51bGwgJiYgY3VycmVudERlZmluaXRpb24ubGVuZ3RoKCk+MCkKCQl7CQoJCQlyZXR1cm4gY3VycmVudERlZmluaXRpb247CgkJfQoJCXJldHVybiBudWxsOwoJfQoJCglwcml2YXRlIHZvaWQgc2VsZWN0U2VydmVyRGVmaW5pdGlvbigpCgl7CgkJU3RyaW5nIGN1cnJlbnREZWZpbml0aW9uID0gZ2V0U2VydmVyRGVmaW5pdGlvbklkKCk7CgkJaW50IHNlbGVjdEluZGV4ID0gMDsKCQlpZihjdXJyZW50RGVmaW5pdGlvbiAhPSBudWxsKQoJCXsJCgkJCXNlbGVjdEluZGV4ID0gIGZTZXJ2ZXJDb21iby5pbmRleE9mKGN1cnJlbnREZWZpbml0aW9uKTsKCQkJaWYoc2VsZWN0SW5kZXg8MCkKCQkJCXNlbGVjdEluZGV4ID0wOwoJCX0KCQlmU2VydmVyQ29tYm8uc2VsZWN0KHNlbGVjdEluZGV4KTsKCX0KCQoJCgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkud2l6YXJkLklXaXphcmRGcmFnbWVudCNlbnRlcigpCgkgKi8KCXB1YmxpYyB2b2lkIGVudGVyKCkgewoJCVN0cmluZyBzZXJ2ZXJEZWZpbml0aW9uID0gZ2V0U2VydmVyRGVmaW5pdGlvbklkKCk7CgkJaWYoc2VydmVyRGVmaW5pdGlvbiE9bnVsbCAmJiBzZXJ2ZXJEZWZpbml0aW9uLmxlbmd0aCgpPjApCgkJewoJCQlzZWxlY3RTZXJ2ZXJEZWZpbml0aW9uKCk7CgkgICAgICAgIE1hcCBwcm9wZXJ0aWVzID0gbnVsbDsKCSAgICAgICAgaWYgKGdldFJ1bnRpbWVEZWxlZ2F0ZSgpICE9IG51bGwpIHsKCSAgICAgICAgICAgIHByb3BlcnRpZXMgPSBnZXRSdW50aW1lRGVsZWdhdGUoKS5nZXRBdHRyaWJ1dGUoR2VuZXJpY1NlcnZlclJ1bnRpbWUuU0VSVkVSX0lOU1RBTkNFX1BST1BFUlRJRVMsKE1hcCkgbnVsbCk7CgkgICAgICAgIH0KCSAgICAgICAgU2VydmVyUnVudGltZSBkZWZpbml0aW9uID0gZ2V0U2VydmVyVHlwZURlZmluaXRpb24oc2VydmVyRGVmaW5pdGlvbixwcm9wZXJ0aWVzKTsKCSAgICAgICAgZlNlcnZlclBhbmVsLnJlc2V0KGRlZmluaXRpb24sU2VydmVyVHlwZURlZmluaXRpb25Hcm91cC5DT05URVhUX1JVTlRJTUUsIHByb3BlcnRpZXMpOwoJCX0KCX0KCQoJLyogKG5vbi1KYXZhZG9jKQoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLndpemFyZC5JV2l6YXJkRnJhZ21lbnQjZXhpdCgpCgkgKi8KCXB1YmxpYyB2b2lkIGV4aXQoKSB7CgkgICAgdHJ5IHsKCSAgICAgICAgZ2V0UnVudGltZURlbGVnYXRlKCkuZ2V0UnVudGltZVdvcmtpbmdDb3B5KCkuc2F2ZSh0cnVlLG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJICAgIH0KCSAgICBjYXRjaChFeGNlcHRpb24gZSl7Ly91bmhhbmRsZWQKCSAgICB9CiAgICAgICAgZlJ1bnRpbWVEZWxlZ2F0ZT1udWxsOwogICAgICAgIAoJfQoJcHJvdGVjdGVkIFN0cmluZyBnZXRTZWxlY3RlZFNlcnZlclR5cGUoKXsKCSAgIHJldHVybiAgZlNlbGVjdGVkU2VydmVyVHlwZTsKCX0KCXByb3RlY3RlZCBNYXAgZ2V0U2VydmVyUnVudGltZVByb3BlcnRpZXMoKXsKCSAgICByZXR1cm4gZlNlcnZlclJ1bnRpbWVQcm9wZXJ0aWVzOyAKCX0KCglwcml2YXRlIFN0cmluZyBjcmVhdGVOYW1lKCkKCXsKCSAgICBTdHJpbmcgc2VsZWN0ZWQgPSBnZXRTZWxlY3RlZFNlcnZlclR5cGUoKTsKCSAgICBSdW50aW1lRGVsZWdhdGUgZGwgPSBnZXRSdW50aW1lRGVsZWdhdGUoKTsKCSAgICBJUnVudGltZVR5cGUgcnVudGltZVR5cGUgPSBkbC5nZXRSdW50aW1lKCkuZ2V0UnVudGltZVR5cGUoKTsKCSAgICBTdHJpbmcgbmFtZSA9IEdlbmVyaWNTZXJ2ZXJVSU1lc3NhZ2VzLmdldEZvcm1hdHRlZFN0cmluZygicnVudGltZU5hbWUiLCBuZXcgU3RyaW5nW10ge3NlbGVjdGVkLHJ1bnRpbWVUeXBlLmdldE5hbWUoKX0pOwoJICAgIAoJCQoJCUlSdW50aW1lW10gbGlzdCA9IFNlcnZlckNvcmUuZ2V0UnVudGltZXMoKTsKCQkKCQlpbnQgc3VmZml4ID0gMTsKCQlTdHJpbmcgc3VmZml4TmFtZT1uYW1lOwoJCWZvcihpbnQgaT0wO2k8bGlzdC5sZW5ndGg7aSsrKQoJICAgIHsKCSAgICAgICAgaWYobGlzdFtpXS5nZXROYW1lKCkuZXF1YWxzKG5hbWUpfHwgbGlzdFtpXS5nZXROYW1lKCkuZXF1YWxzKHN1ZmZpeE5hbWUpKQoJICAgICAgICAgICAgc3VmZml4Kys7CgkgICAgICAgIHN1ZmZpeE5hbWU9IG5hbWUrIiAiK3N1ZmZpeDsKCSAgICB9CgkgICAgCgkJaWYoc3VmZml4PjEpCgkJICAgIHJldHVybiBzdWZmaXhOYW1lOwoJICAgIHJldHVybiBuYW1lOwoJfQoJCglwcml2YXRlIFJ1bnRpbWVEZWxlZ2F0ZSBnZXRSdW50aW1lRGVsZWdhdGUoKQoJewoJCWlmKGZSdW50aW1lRGVsZWdhdGUgPT0gbnVsbCkKCQl7CQoJCSAgICBJUnVudGltZVdvcmtpbmdDb3B5IHdjID0gKElSdW50aW1lV29ya2luZ0NvcHkpZ2V0VGFza01vZGVsKCkuZ2V0T2JqZWN0KElUYXNrTW9kZWwuVEFTS19SVU5USU1FKTsKCQkgICAgaWYod2M9PW51bGwpCgkJICAgICAgICByZXR1cm4gbnVsbDsKCQkgICAgZlJ1bnRpbWVEZWxlZ2F0ZSA9IChSdW50aW1lRGVsZWdhdGUpd2MuZ2V0QWRhcHRlcihSdW50aW1lRGVsZWdhdGUuY2xhc3MpOwoJCX0KCQlyZXR1cm4gZlJ1bnRpbWVEZWxlZ2F0ZTsKCX0KICAgIC8qIChub24tSmF2YWRvYykKICAgICAqIEBzZWUgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmludGVybmFsLnVpLlNlcnZlckRlZmluaXRpb25UeXBlQXdhcmVXaXphcmRGcmFnbWVudCNkZXNjcmlwdGlvbigpCiAgICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgZGVzY3JpcHRpb24oKSB7CiAgICAgICAgcmV0dXJuICBHZW5lcmljU2VydmVyVUlNZXNzYWdlcy5nZXRTdHJpbmcoInJ1bnRpbWVXaXphcmREZXNjcmlwdGlvbiIpOwogICAgfQogICAgLyogKG5vbi1KYXZhZG9jKQogICAgICogQHNlZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuaW50ZXJuYWwudWkuU2VydmVyRGVmaW5pdGlvblR5cGVBd2FyZVdpemFyZEZyYWdtZW50I3RpdGxlKCkKICAgICAqLwogICAgcHVibGljIFN0cmluZyB0aXRsZSgpIHsKICAgICAgICByZXR1cm4gR2VuZXJpY1NlcnZlclVJTWVzc2FnZXMuZ2V0U3RyaW5nKCJydW50aW1lV2l6YXJkVGl0bGUiKTsKICAgIH0KICAgIAogICAgLyogKG5vbi1KYXZhZG9jKQogICAgICogQHNlZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuaW50ZXJuYWwudWkuU2VydmVyRGVmaW5pdGlvblR5cGVBd2FyZVdpemFyZEZyYWdtZW50I3NlcnZlckRlZmluaXRpb25UeXBlUHJvcGVydGllc0NoYW5nZWQoKQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXJ2ZXJEZWZpbml0aW9uVHlwZVByb3BlcnRpZXNDaGFuZ2VkKCkgewoJCWZTZWxlY3RlZFNlcnZlclR5cGUgPSBmU2VydmVyQ29tYm8uZ2V0SXRlbShmU2VydmVyQ29tYm8uZ2V0U2VsZWN0aW9uSW5kZXgoKSk7CiAgICAgICAgZlNlcnZlclJ1bnRpbWVQcm9wZXJ0aWVzID0gZlNlcnZlclBhbmVsLmdldFByb3BlcnRpZXMoKTsKICAgCQlTdHJpbmcgc2VsZWN0ZWQgPSBnZXRTZWxlY3RlZFNlcnZlclR5cGUoKTsKCQlNYXAgcHJvcGVydGllcyA9IGdldFNlcnZlclJ1bnRpbWVQcm9wZXJ0aWVzKCk7CgkJUnVudGltZURlbGVnYXRlIGRsID0gZ2V0UnVudGltZURlbGVnYXRlKCk7ICAgICAgIAkJCgkJZGwuc2V0QXR0cmlidXRlKEdlbmVyaWNTZXJ2ZXJSdW50aW1lLlNFUlZFUl9ERUZJTklUSU9OX0lELCBzZWxlY3RlZCk7CgkJZGwuc2V0QXR0cmlidXRlKEdlbmVyaWNTZXJ2ZXJSdW50aW1lLlNFUlZFUl9JTlNUQU5DRV9QUk9QRVJUSUVTLHByb3BlcnRpZXMpOwoJCWRsLmdldFJ1bnRpbWVXb3JraW5nQ29weSgpLnNldE5hbWUoY3JlYXRlTmFtZSgpKTsKCQkKCQl2YWxpZGF0ZSgpOwogICB9CiAgICAKICAgIHByaXZhdGUgdm9pZCB2YWxpZGF0ZSgpCiAgICB7CgkJaWYgKGdldFJ1bnRpbWVEZWxlZ2F0ZSgpID09IG51bGwpIHsKCQkJdGhpcy5nZXRXaXphcmQoKS5zZXRNZXNzYWdlKCIiLCBJTWVzc2FnZVByb3ZpZGVyLkVSUk9SKTsKCQkJcmV0dXJuOwoJCX0KCQlJU3RhdHVzIHN0YXR1cyA9IGdldFJ1bnRpbWVEZWxlZ2F0ZSgpLnZhbGlkYXRlKCk7CgkJaWYgKHN0YXR1cyA9PSBudWxsIHx8IHN0YXR1cy5pc09LKCkpCgkJCWdldFdpemFyZCgpLnNldE1lc3NhZ2UobnVsbCwgSU1lc3NhZ2VQcm92aWRlci5OT05FKTsKCQllbHNlCgkJCWdldFdpemFyZCgpLnNldE1lc3NhZ2Uoc3RhdHVzLmdldE1lc3NhZ2UoKSwgSU1lc3NhZ2VQcm92aWRlci5FUlJPUik7CgkJZ2V0V2l6YXJkKCkudXBkYXRlKCk7CiAgICB9Cn0K