LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuZWRpdG9yOwoKaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VFdmVudDsKaW1wb3J0IGphdmEuYmVhbnMuUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVdvcmtzcGFjZVJvb3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5SZXNvdXJjZXNQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuQ29yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoQ29uZmlndXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25UeXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoTWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLnVpLkRlYnVnVUlUb29sczsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLndpbmRvdy5XaW5kb3c7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy4qOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkJ1dHRvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbWJvOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuR3JvdXA7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNwaW5uZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UZXh0OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSUVkaXRvcklucHV0OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSUVkaXRvclNpdGU7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5QbGF0Zm9ybVVJOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZGlhbG9ncy5Db250YWluZXJTZWxlY3Rpb25EaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5mb3Jtcy5Gb3JtQ29sb3JzOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZm9ybXMuZXZlbnRzLkh5cGVybGlua0FkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5mb3Jtcy5ldmVudHMuSHlwZXJsaW5rRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5mb3Jtcy53aWRnZXRzLio7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5oZWxwLklXb3JrYmVuY2hIZWxwU3lzdGVtOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlNlcnZlclR5cGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUudXRpbC5Tb2NrZXRVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5lZGl0b3IuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuQ29udGV4dElkczsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuTWVzc2FnZXM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLlNlcnZlclVJUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC5UcmFjZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuY29tbWFuZC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC53aXphcmQuQ2xvc2FibGVXaXphcmREaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLndpemFyZC5UYXNrV2l6YXJkOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC53aXphcmQuV2l6YXJkVGFza1V0aWw7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLndpemFyZC5XaXphcmRGcmFnbWVudDsKLyoqCiAqIFNlcnZlciBnZW5lcmFsIGVkaXRvciBwYWdlLgogKi8KcHVibGljIGNsYXNzIE92ZXJ2aWV3RWRpdG9yUGFydCBleHRlbmRzIFNlcnZlckVkaXRvclBhcnQgewoJcHJvdGVjdGVkIFRleHQgc2VydmVyTmFtZTsKCXByb3RlY3RlZCBUZXh0IHNlcnZlckNvbmZpZ3VyYXRpb25OYW1lOwoJcHJvdGVjdGVkIFRleHQgaG9zdG5hbWU7Cglwcm90ZWN0ZWQgQ29tYm8gcnVudGltZUNvbWJvOwoJcHJvdGVjdGVkIEJ1dHRvbiBhdXRvUHVibGlzaERlZmF1bHQ7Cglwcm90ZWN0ZWQgQnV0dG9uIGF1dG9QdWJsaXNoT3ZlcnJpZGU7Cglwcm90ZWN0ZWQgU3Bpbm5lciBhdXRvUHVibGlzaFRpbWU7CgoJcHJvdGVjdGVkIGJvb2xlYW4gdXBkYXRpbmc7CgoJcHJvdGVjdGVkIElSdW50aW1lW10gcnVudGltZXM7CgoJcHJvdGVjdGVkIFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXI7CgoJLyoqCgkgKiBPdmVydmlld0VkaXRvclBhcnQgY29uc3RydWN0b3IgY29tbWVudC4KCSAqLwoJcHVibGljIE92ZXJ2aWV3RWRpdG9yUGFydCgpIHsKCQlzdXBlcigpOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGFkZENoYW5nZUxpc3RlbmVyKCkgewoJCWxpc3RlbmVyID0gbmV3IFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHByb3BlcnR5Q2hhbmdlKFByb3BlcnR5Q2hhbmdlRXZlbnQgZXZlbnQpIHsKCQkJCWlmICh1cGRhdGluZykKCQkJCQlyZXR1cm47CgkJCQl1cGRhdGluZyA9IHRydWU7CgkJCQlpZiAoZXZlbnQuZ2V0UHJvcGVydHlOYW1lKCkuZXF1YWxzKCJuYW1lIikpCgkJCQkJdXBkYXRlTmFtZXMoKTsKCQkJCWVsc2UgaWYgKGV2ZW50LmdldFByb3BlcnR5TmFtZSgpLmVxdWFscygiaG9zdG5hbWUiKSAmJiBob3N0bmFtZSAhPSBudWxsKSB7CgkJCQkJaG9zdG5hbWUuc2V0VGV4dCgoU3RyaW5nKSBldmVudC5nZXROZXdWYWx1ZSgpKTsKCQkJCX0gZWxzZSBpZiAoZXZlbnQuZ2V0UHJvcGVydHlOYW1lKCkuZXF1YWxzKCJydW50aW1lLWlkIikpIHsKCQkJCQlTdHJpbmcgcnVudGltZUlkID0gKFN0cmluZykgZXZlbnQuZ2V0TmV3VmFsdWUoKTsKCQkJCQlJUnVudGltZSBydW50aW1lID0gbnVsbDsKCQkJCQlpZiAocnVudGltZUlkICE9IG51bGwpCgkJCQkJCXJ1bnRpbWUgPSBTZXJ2ZXJDb3JlLmZpbmRSdW50aW1lKHJ1bnRpbWVJZCk7CgkJCQkJaW50IHNpemUgPSBydW50aW1lcy5sZW5ndGg7CgkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQkJaWYgKHJ1bnRpbWVzW2ldLmVxdWFscyhydW50aW1lKSkKCQkJCQkJCXJ1bnRpbWVDb21iby5zZWxlY3QoaSk7CgkJCQkJfQoJCQkJfSBlbHNlIGlmIChldmVudC5nZXRQcm9wZXJ0eU5hbWUoKS5lcXVhbHMoImNvbmZpZ3VyYXRpb24taWQiKSAmJiBzZXJ2ZXJDb25maWd1cmF0aW9uTmFtZSAhPSBudWxsKSB7CgkJCQkJU3RyaW5nIHBhdGggPSAoU3RyaW5nKSBldmVudC5nZXROZXdWYWx1ZSgpOwoJCQkJCXNlcnZlckNvbmZpZ3VyYXRpb25OYW1lLnNldFRleHQocGF0aCk7CgkJCQl9IGVsc2UgaWYgKGV2ZW50LmdldFByb3BlcnR5TmFtZSgpLmVxdWFscygiYXV0by1wdWJsaXNoLXRpbWUiKSkgewoJCQkJCUludGVnZXIgY3VyQXV0b1B1Ymxpc2hUaW1lID0gKEludGVnZXIpZXZlbnQuZ2V0TmV3VmFsdWUoKTsKCQkJCQlhdXRvUHVibGlzaFRpbWUuc2V0U2VsZWN0aW9uKGN1ckF1dG9QdWJsaXNoVGltZS5pbnRWYWx1ZSgpKTsKCQkJCX0gZWxzZSBpZiAoZXZlbnQuZ2V0UHJvcGVydHlOYW1lKCkuZXF1YWxzKCJhdXRvLXB1Ymxpc2gtZGVmYXVsdCIpKSB7CgkJCQkJQm9vbGVhbiBjdXJBdXRvUHVibGlzaFRpbWUgPSAoQm9vbGVhbilldmVudC5nZXROZXdWYWx1ZSgpOwoJCQkJCWF1dG9QdWJsaXNoRGVmYXVsdC5zZXRTZWxlY3Rpb24oY3VyQXV0b1B1Ymxpc2hUaW1lLmJvb2xlYW5WYWx1ZSgpKTsKCQkJCQlhdXRvUHVibGlzaE92ZXJyaWRlLnNldFNlbGVjdGlvbighY3VyQXV0b1B1Ymxpc2hUaW1lLmJvb2xlYW5WYWx1ZSgpKTsKCQkJCX0KCQkJCXVwZGF0aW5nID0gZmFsc2U7CgkJCX0KCQl9OwoJCWlmIChzZXJ2ZXIgIT0gbnVsbCkKCQkJc2VydmVyLmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIobGlzdGVuZXIpOwoJfQoKCXByb3RlY3RlZCB2b2lkIHVwZGF0ZU5hbWVzKCkgewoJCWlmIChzZXJ2ZXJOYW1lICE9IG51bGwpCgkJCXNlcnZlck5hbWUuc2V0VGV4dChzZXJ2ZXIuZ2V0TmFtZSgpKTsKCX0KCgkvKioKCSAqIENyZWF0ZXMgdGhlIFNXVCBjb250cm9scyBmb3IgdGhpcyB3b3JrYmVuY2ggcGFydC4KCSAqCgkgKiBAcGFyYW0gcGFyZW50IHRoZSBwYXJlbnQgY29udHJvbAoJICovCglwdWJsaWMgZmluYWwgdm9pZCBjcmVhdGVQYXJ0Q29udHJvbChmaW5hbCBDb21wb3NpdGUgcGFyZW50KSB7CgkJRm9ybVRvb2xraXQgdG9vbGtpdCA9IGdldEZvcm1Ub29sa2l0KHBhcmVudC5nZXREaXNwbGF5KCkpOwoJCQoJCVNjcm9sbGVkRm9ybSBmb3JtID0gdG9vbGtpdC5jcmVhdGVTY3JvbGxlZEZvcm0ocGFyZW50KTsKCQlmb3JtLnNldFRleHQoTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdQYWdlVGl0bGUpOwoJCWZvcm0uZ2V0Qm9keSgpLnNldExheW91dChuZXcgR3JpZExheW91dCgpKTsKCQkKCQlDb21wb3NpdGUgY29sdW1uQ29tcCA9IHRvb2xraXQuY3JlYXRlQ29tcG9zaXRlKGZvcm0uZ2V0Qm9keSgpKTsKCQlHcmlkTGF5b3V0IGxheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJbGF5b3V0Lm51bUNvbHVtbnMgPSAyOwoJCS8vbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDEwOwoJCS8vbGF5b3V0Lm1hcmdpbldpZHRoID0gMTA7CgkJbGF5b3V0LnZlcnRpY2FsU3BhY2luZyA9IDA7CgkJbGF5b3V0Lmhvcml6b250YWxTcGFjaW5nID0gMTA7CgkJY29sdW1uQ29tcC5zZXRMYXlvdXQobGF5b3V0KTsKCQljb2x1bW5Db21wLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0ZJTEwpKTsKCQkKCQkvLyBsZWZ0IGNvbHVtbgoJCUNvbXBvc2l0ZSBsZWZ0Q29sdW1uQ29tcCA9IHRvb2xraXQuY3JlYXRlQ29tcG9zaXRlKGNvbHVtbkNvbXApOwoJCWxheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7CgkJbGF5b3V0Lm1hcmdpbldpZHRoID0gMDsKCQlsYXlvdXQudmVydGljYWxTcGFjaW5nID0gMTA7CgkJbGF5b3V0Lmhvcml6b250YWxTcGFjaW5nID0gMDsKCQlsZWZ0Q29sdW1uQ29tcC5zZXRMYXlvdXQobGF5b3V0KTsKCQlsZWZ0Q29sdW1uQ29tcC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKSk7CgkJCgkJU2VjdGlvbiBzZWN0aW9uID0gdG9vbGtpdC5jcmVhdGVTZWN0aW9uKGxlZnRDb2x1bW5Db21wLCBFeHBhbmRhYmxlQ29tcG9zaXRlLlRXSVNUSUV8RXhwYW5kYWJsZUNvbXBvc2l0ZS5FWFBBTkRFRCB8IEV4cGFuZGFibGVDb21wb3NpdGUuVElUTEVfQkFSIHwgU2VjdGlvbi5ERVNDUklQVElPTiB8IEV4cGFuZGFibGVDb21wb3NpdGUuRk9DVVNfVElUTEUpOwoJCXNlY3Rpb24uc2V0VGV4dChNZXNzYWdlcy5zZXJ2ZXJFZGl0b3JPdmVydmlld1NlY3Rpb24pOwoJCXNlY3Rpb24uc2V0RGVzY3JpcHRpb24oTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdEZXNjcmlwdGlvbik7CgkJc2VjdGlvbi5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKSk7CgoJCUNvbXBvc2l0ZSBjb21wb3NpdGUgPSB0b29sa2l0LmNyZWF0ZUNvbXBvc2l0ZShzZWN0aW9uKTsKCQlsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5udW1Db2x1bW5zID0gMjsKCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gNTsKCQlsYXlvdXQubWFyZ2luV2lkdGggPSAxMDsKCQlsYXlvdXQudmVydGljYWxTcGFjaW5nID0gNTsKCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSAxNTsKCQljb21wb3NpdGUuc2V0TGF5b3V0KGxheW91dCk7CgkJY29tcG9zaXRlLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0ZJTEwpKTsKCQlJV29ya2JlbmNoSGVscFN5c3RlbSB3aHMgPSBQbGF0Zm9ybVVJLmdldFdvcmtiZW5jaCgpLmdldEhlbHBTeXN0ZW0oKTsKCQl3aHMuc2V0SGVscChjb21wb3NpdGUsIENvbnRleHRJZHMuRURJVE9SX09WRVJWSUVXX1BBR0UpOwoJCXRvb2xraXQucGFpbnRCb3JkZXJzRm9yKGNvbXBvc2l0ZSk7CgkJc2VjdGlvbi5zZXRDbGllbnQoY29tcG9zaXRlKTsKCgkJLy8gc2VydmVyIG5hbWUKCQlpZiAoc2VydmVyICE9IG51bGwpIHsKCQkJY3JlYXRlTGFiZWwodG9vbGtpdCwgY29tcG9zaXRlLCBNZXNzYWdlcy5zZXJ2ZXJFZGl0b3JPdmVydmlld1NlcnZlck5hbWUpOwoJCQkKCQkJc2VydmVyTmFtZSA9IHRvb2xraXQuY3JlYXRlVGV4dChjb21wb3NpdGUsIHNlcnZlci5nZXROYW1lKCkpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJCXNlcnZlck5hbWUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJc2VydmVyTmFtZS5hZGRNb2RpZnlMaXN0ZW5lcihuZXcgTW9kaWZ5TGlzdGVuZXIoKSB7CgkJCQlwdWJsaWMgdm9pZCBtb2RpZnlUZXh0KE1vZGlmeUV2ZW50IGUpIHsKCQkJCQlpZiAodXBkYXRpbmcpCgkJCQkJCXJldHVybjsKCQkJCQl1cGRhdGluZyA9IHRydWU7CgkJCQkJZXhlY3V0ZShuZXcgU2V0U2VydmVyTmFtZUNvbW1hbmQoZ2V0U2VydmVyKCksIHNlcnZlck5hbWUuZ2V0VGV4dCgpKSk7CgkJCQkJdXBkYXRpbmcgPSBmYWxzZTsKCQkJCX0KCQkJfSk7CgkJCXdocy5zZXRIZWxwKHNlcnZlck5hbWUsIENvbnRleHRJZHMuRURJVE9SX1NFUlZFUik7CgkJfQoJCQoJCS8vIGhvc3RuYW1lCgkJaWYgKHNlcnZlciAhPSBudWxsKSB7CgkJCWNyZWF0ZUxhYmVsKHRvb2xraXQsIGNvbXBvc2l0ZSwgTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdTZXJ2ZXJIb3N0bmFtZSk7CgkJCQoJCQlob3N0bmFtZSA9IHRvb2xraXQuY3JlYXRlVGV4dChjb21wb3NpdGUsIHNlcnZlci5nZXRIb3N0KCkpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJCWhvc3RuYW1lLnNldExheW91dERhdGEoZGF0YSk7CgkJCWhvc3RuYW1lLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJCXB1YmxpYyB2b2lkIG1vZGlmeVRleHQoTW9kaWZ5RXZlbnQgZSkgewoJCQkJCWlmICh1cGRhdGluZykKCQkJCQkJcmV0dXJuOwoJCQkJCXVwZGF0aW5nID0gdHJ1ZTsKCQkJCQlleGVjdXRlKG5ldyBTZXRTZXJ2ZXJIb3N0bmFtZUNvbW1hbmQoZ2V0U2VydmVyKCksIGhvc3RuYW1lLmdldFRleHQoKSkpOwoJCQkJCXVwZGF0aW5nID0gZmFsc2U7CgkJCQl9CgkJCX0pOwoJCQl3aHMuc2V0SGVscChob3N0bmFtZSwgQ29udGV4dElkcy5FRElUT1JfSE9TVE5BTUUpOwoJCX0KCQkKCQkvLyBydW50aW1lCgkJaWYgKHNlcnZlciAhPSBudWxsICYmIHNlcnZlci5nZXRTZXJ2ZXJUeXBlKCkgIT0gbnVsbCAmJiBzZXJ2ZXIuZ2V0U2VydmVyVHlwZSgpLmhhc1J1bnRpbWUoKSkgewoJCQlmaW5hbCBJUnVudGltZSBydW50aW1lID0gc2VydmVyLmdldFJ1bnRpbWUoKTsKCQkJY3JlYXRlTGFiZWwodG9vbGtpdCwgY29tcG9zaXRlLCBNZXNzYWdlcy5zZXJ2ZXJFZGl0b3JPdmVydmlld1J1bnRpbWUpOwoJCQkKCQkJSVJ1bnRpbWVUeXBlIHJ1bnRpbWVUeXBlID0gc2VydmVyLmdldFNlcnZlclR5cGUoKS5nZXRSdW50aW1lVHlwZSgpOwoJCQlydW50aW1lcyA9IFNlcnZlclVJUGx1Z2luLmdldFJ1bnRpbWVzKHJ1bnRpbWVUeXBlKTsKCQkJCgkJCWlmIChydW50aW1lcyA9PSBudWxsIHx8IHJ1bnRpbWVzLmxlbmd0aCA9PSAwKQoJCQkJdG9vbGtpdC5jcmVhdGVMYWJlbChjb21wb3NpdGUsICIiKTsKCQkJZWxzZSBpZiAocnVudGltZXMubGVuZ3RoID09IDEpCgkJCQl0b29sa2l0LmNyZWF0ZUxhYmVsKGNvbXBvc2l0ZSwgcnVudGltZS5nZXROYW1lKCkpOwoJCQllbHNlIHsKCQkJCXJ1bnRpbWVDb21ibyA9IG5ldyBDb21ibyhjb21wb3NpdGUsIFNXVC5SRUFEX09OTFkpOwoJCQkJcnVudGltZUNvbWJvLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCkpOwoJCQkJdXBkYXRlUnVudGltZUNvbWJvKCk7CgkJCQkKCQkJCWludCBzaXplID0gcnVudGltZXMubGVuZ3RoOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQlpZiAocnVudGltZXNbaV0uZXF1YWxzKHJ1bnRpbWUpKQoJCQkJCQlydW50aW1lQ29tYm8uc2VsZWN0KGkpOwoJCQkJfQoJCQkJCgkJCQlydW50aW1lQ29tYm8uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgewoJCQkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCQkJdHJ5IHsKCQkJCQkJCWlmICh1cGRhdGluZykKCQkJCQkJCQlyZXR1cm47CgkJCQkJCQl1cGRhdGluZyA9IHRydWU7CgkJCQkJCQlJUnVudGltZSBuZXdSdW50aW1lID0gcnVudGltZXNbcnVudGltZUNvbWJvLmdldFNlbGVjdGlvbkluZGV4KCldOwoJCQkJCQkJZXhlY3V0ZShuZXcgU2V0U2VydmVyUnVudGltZUNvbW1hbmQoZ2V0U2VydmVyKCksIG5ld1J1bnRpbWUpKTsKCQkJCQkJCXVwZGF0aW5nID0gZmFsc2U7CgkJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewoJCQkJCQkJLy8gaWdub3JlCgkJCQkJCX0KCQkJCQl9CgkJCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCQkJd2lkZ2V0U2VsZWN0ZWQoZSk7CgkJCQkJfQoJCQkJfSk7CgkJCQl3aHMuc2V0SGVscChydW50aW1lQ29tYm8sIENvbnRleHRJZHMuRURJVE9SX1JVTlRJTUUpOwoJCQl9CgkJCQoJCQljcmVhdGVMYWJlbCh0b29sa2l0LCBjb21wb3NpdGUsICIiKTsKCQkJSHlwZXJsaW5rIGxpbmsgPSB0b29sa2l0LmNyZWF0ZUh5cGVybGluayhjb21wb3NpdGUsIE1lc3NhZ2VzLnNlcnZlckVkaXRvck92ZXJ2aWV3UnVudGltZUVkaXQsIFNXVC5OT05FKTsKCQkJbGluay5hZGRIeXBlcmxpbmtMaXN0ZW5lcihuZXcgSHlwZXJsaW5rQWRhcHRlcigpIHsKCQkJCXB1YmxpYyB2b2lkIGxpbmtBY3RpdmF0ZWQoSHlwZXJsaW5rRXZlbnQgZSkgewoJCQkJCWVkaXRSdW50aW1lKHJ1bnRpbWUpOwoJCQkJfQoJCQl9KTsKCQkJbGluay5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0VORCkpOwoJCX0KCQkKCQkvLyBzZXJ2ZXIgY29uZmlndXJhdGlvbiBwYXRoCgkJaWYgKHNlcnZlciAhPSBudWxsICYmIHNlcnZlci5nZXRTZXJ2ZXJUeXBlKCkuaGFzU2VydmVyQ29uZmlndXJhdGlvbigpKSB7CgkJCWNyZWF0ZUxhYmVsKHRvb2xraXQsIGNvbXBvc2l0ZSwgTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdTZXJ2ZXJDb25maWd1cmF0aW9uUGF0aCk7CgkJCQoJCQlJRm9sZGVyIGZvbGRlciA9IHNlcnZlci5nZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCk7CgkJCWlmIChmb2xkZXIgPT0gbnVsbCkKCQkJCXNlcnZlckNvbmZpZ3VyYXRpb25OYW1lID0gdG9vbGtpdC5jcmVhdGVUZXh0KGNvbXBvc2l0ZSwgTWVzc2FnZXMuZWxlbWVudFVua25vd25OYW1lKTsKCQkJZWxzZQoJCQkJc2VydmVyQ29uZmlndXJhdGlvbk5hbWUgPSB0b29sa2l0LmNyZWF0ZVRleHQoY29tcG9zaXRlLCAiIiArIHNlcnZlci5nZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCkuZ2V0RnVsbFBhdGgoKSk7CgkJCS8vaWYgKCFzZXJ2ZXIuZ2V0U2VydmVyQ29uZmlndXJhdGlvbigpLmdldEZ1bGxQYXRoKCkudG9GaWxlKCkuZXhpc3RzKCkpCgkJCQoJCQlzZXJ2ZXJDb25maWd1cmF0aW9uTmFtZS5zZXRFZGl0YWJsZShmYWxzZSk7CgkJCXNlcnZlckNvbmZpZ3VyYXRpb25OYW1lLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCkpOwoJCQkKCQkJd2hzLnNldEhlbHAoc2VydmVyQ29uZmlndXJhdGlvbk5hbWUsIENvbnRleHRJZHMuRURJVE9SX0NPTkZJR1VSQVRJT04pOwoJCQkKCQkJY3JlYXRlTGFiZWwodG9vbGtpdCwgY29tcG9zaXRlLCAiIik7CgkJCWZpbmFsIElGb2xkZXIgY3VycmVudEZvbGRlciA9IHNlcnZlci5nZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCk7CgkJCUh5cGVybGluayBsaW5rID0gdG9vbGtpdC5jcmVhdGVIeXBlcmxpbmsoY29tcG9zaXRlLCBNZXNzYWdlcy5zZXJ2ZXJFZGl0b3JPdmVydmlld1NlcnZlckNvbmZpZ3VyYXRpb25FZGl0LCBTV1QuTk9ORSk7CgkJCWxpbmsuYWRkSHlwZXJsaW5rTGlzdGVuZXIobmV3IEh5cGVybGlua0FkYXB0ZXIoKSB7CgkJCQlwdWJsaWMgdm9pZCBsaW5rQWN0aXZhdGVkKEh5cGVybGlua0V2ZW50IGUpIHsKCQkJCQlDb250YWluZXJTZWxlY3Rpb25EaWFsb2cgZGlhbG9nID0gbmV3IENvbnRhaW5lclNlbGVjdGlvbkRpYWxvZyhzZXJ2ZXJDb25maWd1cmF0aW9uTmFtZS5nZXRTaGVsbCgpLAoJCQkJCQljdXJyZW50Rm9sZGVyLCB0cnVlLCBNZXNzYWdlcy5zZXJ2ZXJFZGl0b3JPdmVydmlld1NlcnZlckNvbmZpZ3VyYXRpb25FZGl0TWVzc2FnZSk7CgkJCQkJZGlhbG9nLnNob3dDbG9zZWRQcm9qZWN0cyhmYWxzZSk7CgkJCQkJCgkJCQkJaWYgKGRpYWxvZy5vcGVuKCkgIT0gV2luZG93LkNBTkNFTCkgewoJCQkJCQlPYmplY3RbXSByZXN1bHQgPSBkaWFsb2cuZ2V0UmVzdWx0KCk7CgkJCQkJCWlmIChyZXN1bHQgIT0gbnVsbCAmJiByZXN1bHQubGVuZ3RoID09IDEpIHsKCQkJCQkJCUlQYXRoIHBhdGggPSAoSVBhdGgpIHJlc3VsdFswXTsKCQkJCQkJCQoJCQkJCQkJSVdvcmtzcGFjZVJvb3Qgcm9vdCA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCk7CgkJCQkJCQlJUmVzb3VyY2UgcmVzb3VyY2UgPSByb290LmZpbmRNZW1iZXIocGF0aCk7CgkJCQkJCQlpZiAocmVzb3VyY2UgIT0gbnVsbCAmJiByZXNvdXJjZSBpbnN0YW5jZW9mIElGb2xkZXIpIHsKCQkJCQkJCQlJRm9sZGVyIGZvbGRlcjIgPSAoSUZvbGRlcikgcmVzb3VyY2U7CgkJCQkJCQkKCQkJCQkJCQlpZiAodXBkYXRpbmcpCgkJCQkJCQkJCXJldHVybjsKCQkJCQkJCQl1cGRhdGluZyA9IHRydWU7CgkJCQkJCQkJZXhlY3V0ZShuZXcgU2V0U2VydmVyQ29uZmlndXJhdGlvbkZvbGRlckNvbW1hbmQoZ2V0U2VydmVyKCksIGZvbGRlcjIpKTsKCQkJCQkJCQlzZXJ2ZXJDb25maWd1cmF0aW9uTmFtZS5zZXRUZXh0KGZvbGRlcjIuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpKTsKCQkJCQkJCQl1cGRhdGluZyA9IGZhbHNlOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9KTsKCQkJbGluay5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0VORCkpOwoJCX0KCQkKCQkvLyBhdXRvLXB1Ymxpc2gKCQlpZiAoc2VydmVyICE9IG51bGwpIHsKCQkJR3JvdXAgZ3JvdXAgPSBuZXcgR3JvdXAoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJCWdyb3VwLnNldEJhY2tncm91bmQoY29tcG9zaXRlLmdldEJhY2tncm91bmQoKSk7CgkJCWdyb3VwLnNldFRleHQoTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdQdWJsaXNoaW5nKTsKCQkJbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQkJbGF5b3V0Lm51bUNvbHVtbnMgPSAyOwoJCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gNTsKCQkJbGF5b3V0Lm1hcmdpbldpZHRoID0gMTA7CgkJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSA1OwoJCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSAxNTsKCQkJZ3JvdXAuc2V0TGF5b3V0KGxheW91dCk7CgkJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJCWdyb3VwLnNldExheW91dERhdGEoZGF0YSk7CgkJCQoJCQlhdXRvUHVibGlzaERlZmF1bHQgPSB0b29sa2l0LmNyZWF0ZUJ1dHRvbihncm91cCwgTWVzc2FnZXMuc2VydmVyRWRpdG9yT3ZlcnZpZXdBdXRvUHVibGlzaERlZmF1bHQsIFNXVC5SQURJTyk7CgkJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJCWF1dG9QdWJsaXNoRGVmYXVsdC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQlmaW5hbCBTZXJ2ZXIgc3ZyID0gKFNlcnZlcikgc2VydmVyOwoJCQlhdXRvUHVibGlzaERlZmF1bHQuc2V0U2VsZWN0aW9uKHN2ci5nZXRBdXRvUHVibGlzaERlZmF1bHQoKSk7CgkJCXdocy5zZXRIZWxwKGF1dG9QdWJsaXNoRGVmYXVsdCwgQ29udGV4dElkcy5FRElUT1JfQVVUT1BVQkxJU0hfREVGQVVMVCk7CgkJCQoJCQlhdXRvUHVibGlzaE92ZXJyaWRlID0gdG9vbGtpdC5jcmVhdGVCdXR0b24oZ3JvdXAsIE1lc3NhZ2VzLnNlcnZlckVkaXRvck92ZXJ2aWV3QXV0b1B1Ymxpc2hPdmVycmlkZSwgU1dULlJBRElPKTsKCQkJYXV0b1B1Ymxpc2hPdmVycmlkZS5zZXRTZWxlY3Rpb24oIXN2ci5nZXRBdXRvUHVibGlzaERlZmF1bHQoKSk7CgkJCXdocy5zZXRIZWxwKGF1dG9QdWJsaXNoT3ZlcnJpZGUsIENvbnRleHRJZHMuRURJVE9SX0FVVE9QVUJMSVNIX09WRVJSSURFKTsKCQkJCgkJCWF1dG9QdWJsaXNoT3ZlcnJpZGUuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQkJaWYgKHVwZGF0aW5nKQoJCQkJCQlyZXR1cm47CgkJCQkJdXBkYXRpbmcgPSB0cnVlOwoJCQkJCWV4ZWN1dGUobmV3IFNldFNlcnZlckF1dG9QdWJsaXNoRGVmYXVsdENvbW1hbmQoZ2V0U2VydmVyKCksIGF1dG9QdWJsaXNoRGVmYXVsdC5nZXRTZWxlY3Rpb24oKSkpOwoJCQkJCXVwZGF0aW5nID0gZmFsc2U7CgkJCQkJYXV0b1B1Ymxpc2hUaW1lLnNldEVuYWJsZWQoYXV0b1B1Ymxpc2hPdmVycmlkZS5nZXRTZWxlY3Rpb24oKSk7CgkJCQl9CgkJCX0pOwoJCQkKCQkJLy9hdXRvUHVibGlzaFRpbWUgPSB0b29sa2l0LmNyZWF0ZVRleHQoY29tcG9zaXRlLCBzdnIuZ2V0QXV0b1B1Ymxpc2hUaW1lKCkgKyAiIik7CgkJCWF1dG9QdWJsaXNoVGltZSA9IG5ldyBTcGlubmVyKGdyb3VwLCBTV1QuQk9SREVSKTsKCQkJYXV0b1B1Ymxpc2hUaW1lLnNldE1pbmltdW0oMCk7CgkJCWF1dG9QdWJsaXNoVGltZS5zZXRNYXhpbXVtKDEyMCk7CgkJCWF1dG9QdWJsaXNoVGltZS5zZXRTZWxlY3Rpb24oc3ZyLmdldEF1dG9QdWJsaXNoVGltZSgpKTsKCQkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCQlhdXRvUHVibGlzaFRpbWUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJYXV0b1B1Ymxpc2hUaW1lLnNldEVuYWJsZWQoYXV0b1B1Ymxpc2hPdmVycmlkZS5nZXRTZWxlY3Rpb24oKSk7CgkJCXdocy5zZXRIZWxwKGF1dG9QdWJsaXNoVGltZSwgQ29udGV4dElkcy5FRElUT1JfQVVUT1BVQkxJU0hfVElNRSk7CgkJCQoJCQlhdXRvUHVibGlzaFRpbWUuYWRkTW9kaWZ5TGlzdGVuZXIobmV3IE1vZGlmeUxpc3RlbmVyKCkgewoJCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQkJaWYgKHVwZGF0aW5nKQoJCQkJCQlyZXR1cm47CgkJCQkJdXBkYXRpbmcgPSB0cnVlOwoJCQkJCXRyeSB7CgkJCQkJCWV4ZWN1dGUobmV3IFNldFNlcnZlckF1dG9QdWJsaXNoVGltZUNvbW1hbmQoZ2V0U2VydmVyKCksIGF1dG9QdWJsaXNoVGltZS5nZXRTZWxlY3Rpb24oKSkpOwoJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewoJCQkJCQkvLyBpZ25vcmUKCQkJCQl9CgkJCQkJdXBkYXRpbmcgPSBmYWxzZTsKCQkJCX0KCQkJfSk7CgkJCQoJCQlJU2VydmVyVHlwZSBzZXJ2ZXJUeXBlID0gc2VydmVyLmdldFNlcnZlclR5cGUoKTsKCQkJaWYgKHNlcnZlclR5cGUuc3VwcG9ydHNMYXVuY2hNb2RlKElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFKSB8fCBzZXJ2ZXJUeXBlLnN1cHBvcnRzTGF1bmNoTW9kZShJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFKQoJCQkJCXx8IHNlcnZlclR5cGUuc3VwcG9ydHNMYXVuY2hNb2RlKElMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERSkpIHsKCQkJCUlMYXVuY2hDb25maWd1cmF0aW9uVHlwZSBsYXVuY2hUeXBlID0gKChTZXJ2ZXJUeXBlKSBzZXJ2ZXJUeXBlKS5nZXRMYXVuY2hDb25maWd1cmF0aW9uVHlwZSgpOwoJCQkJaWYgKGxhdW5jaFR5cGUuaXNQdWJsaWMoKSkgewoJCQkJCUh5cGVybGluayBsaW5rID0gdG9vbGtpdC5jcmVhdGVIeXBlcmxpbmsoY29tcG9zaXRlLCBNZXNzYWdlcy5zZXJ2ZXJFZGl0b3JPdmVydmlld09wZW5MYXVuY2hDb25maWd1cmF0aW9uLCBTV1QuTk9ORSk7CgkJCQkJZGF0YSA9IG5ldyBHcmlkRGF0YSgpOwoJCQkJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCQkJCWxpbmsuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJCQlsaW5rLmFkZEh5cGVybGlua0xpc3RlbmVyKG5ldyBIeXBlcmxpbmtBZGFwdGVyKCkgewoJCQkJCQlwdWJsaWMgdm9pZCBsaW5rQWN0aXZhdGVkKEh5cGVybGlua0V2ZW50IGUpIHsKCQkJCQkJCXRyeSB7CgkJCQkJCQkJSUxhdW5jaENvbmZpZ3VyYXRpb24gbGF1bmNoQ29uZmlnID0gc3ZyLmdldExhdW5jaENvbmZpZ3VyYXRpb24odHJ1ZSwgbnVsbCk7CgkJCQkJCQkJLy8gVE9ETzogdXNlIGNvcnJlY3QgbGF1bmNoIGdyb3VwCgkJCQkJCQkJRGVidWdVSVRvb2xzLm9wZW5MYXVuY2hDb25maWd1cmF0aW9uUHJvcGVydGllc0RpYWxvZyhwYXJlbnQuZ2V0U2hlbGwoKSwgbGF1bmNoQ29uZmlnLCAib3JnLmVjbGlwc2UuZGVidWcudWkubGF1bmNoR3JvdXAucnVuIik7CgkJCQkJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCQkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiQ291bGQgbm90IGNyZWF0ZSBsYXVuY2ggY29uZmlndXJhdGlvbiIsIGNlKTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0pOwoJCQkJfQoJCQl9CgkJfQoJCQoJCWluc2VydFNlY3Rpb25zKGxlZnRDb2x1bW5Db21wLCAib3JnLmVjbGlwc2Uud3N0LnNlcnZlci5lZGl0b3Iub3ZlcnZpZXcubGVmdCIpOwoJCQoJCS8vIHJpZ2h0IGNvbHVtbgoJCUNvbXBvc2l0ZSByaWdodENvbHVtbkNvbXAgPSB0b29sa2l0LmNyZWF0ZUNvbXBvc2l0ZShjb2x1bW5Db21wKTsKCQlsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSAwOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJbGF5b3V0LnZlcnRpY2FsU3BhY2luZyA9IDEwOwoJCWxheW91dC5ob3Jpem9udGFsU3BhY2luZyA9IDA7CgkJcmlnaHRDb2x1bW5Db21wLnNldExheW91dChsYXlvdXQpOwoJCXJpZ2h0Q29sdW1uQ29tcC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKSk7CgkJCgkJaW5zZXJ0U2VjdGlvbnMocmlnaHRDb2x1bW5Db21wLCAib3JnLmVjbGlwc2Uud3N0LnNlcnZlci5lZGl0b3Iub3ZlcnZpZXcucmlnaHQiKTsKCQkKCQlmb3JtLnNldENvbnRlbnQoY29sdW1uQ29tcCk7CgkJZm9ybS5yZWZsb3codHJ1ZSk7CgoJCWluaXRpYWxpemUoKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgZWRpdFJ1bnRpbWUoSVJ1bnRpbWUgcnVudGltZSkgewoJCUlSdW50aW1lV29ya2luZ0NvcHkgcnVudGltZVdvcmtpbmdDb3B5ID0gcnVudGltZS5jcmVhdGVXb3JraW5nQ29weSgpOwoJCWlmIChzaG93V2l6YXJkKHJ1bnRpbWVXb3JraW5nQ29weSkgIT0gV2luZG93LkNBTkNFTCkgewoJCQl0cnkgewoJCQkJcnVudGltZVdvcmtpbmdDb3B5LnNhdmUoZmFsc2UsIG51bGwpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKCQkJCS8vIGlnbm9yZQoJCQl9CgkJfQoJfQoJCglwcm90ZWN0ZWQgaW50IHNob3dXaXphcmQoZmluYWwgSVJ1bnRpbWVXb3JraW5nQ29weSBydW50aW1lV29ya2luZ0NvcHkpIHsKCQlTdHJpbmcgdGl0bGUgPSBNZXNzYWdlcy53aXpFZGl0UnVudGltZVdpemFyZFRpdGxlOwoJCWZpbmFsIFdpemFyZEZyYWdtZW50IGZyYWdtZW50MiA9IFNlcnZlclVJUGx1Z2luLmdldFdpemFyZEZyYWdtZW50KHJ1bnRpbWVXb3JraW5nQ29weS5nZXRSdW50aW1lVHlwZSgpLmdldElkKCkpOwoJCWlmIChmcmFnbWVudDIgPT0gbnVsbCkKCQkJcmV0dXJuIFdpbmRvdy5DQU5DRUw7CgkJCgkJVGFza01vZGVsIHRhc2tNb2RlbCA9IG5ldyBUYXNrTW9kZWwoKTsKCQl0YXNrTW9kZWwucHV0T2JqZWN0KFRhc2tNb2RlbC5UQVNLX1JVTlRJTUUsIHJ1bnRpbWVXb3JraW5nQ29weSk7CgoJCVdpemFyZEZyYWdtZW50IGZyYWdtZW50ID0gbmV3IFdpemFyZEZyYWdtZW50KCkgewoJCQlwcm90ZWN0ZWQgdm9pZCBjcmVhdGVDaGlsZEZyYWdtZW50cyhMaXN0IGxpc3QpIHsKCQkJCWxpc3QuYWRkKGZyYWdtZW50Mik7CgkJCQlsaXN0LmFkZChuZXcgV2l6YXJkRnJhZ21lbnQoKSB7CgkJCQkJcHVibGljIHZvaWQgcGVyZm9ybUZpbmlzaChJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQkJCQkJV2l6YXJkVGFza1V0aWwuc2F2ZVJ1bnRpbWUoZ2V0VGFza01vZGVsKCksIG1vbml0b3IpOwoJCQkJCX0KCQkJCX0pOwoJCQl9CgkJfTsKCQkKCQlUYXNrV2l6YXJkIHdpemFyZCA9IG5ldyBUYXNrV2l6YXJkKHRpdGxlLCBmcmFnbWVudCwgdGFza01vZGVsKTsKCQl3aXphcmQuc2V0Rm9yY2VQcmV2aW91c0FuZE5leHRCdXR0b25zKHRydWUpOwoJCUNsb3NhYmxlV2l6YXJkRGlhbG9nIGRpYWxvZyA9IG5ldyBDbG9zYWJsZVdpemFyZERpYWxvZyhnZXRFZGl0b3JTaXRlKCkuZ2V0U2hlbGwoKSwgd2l6YXJkKTsKCQlyZXR1cm4gZGlhbG9nLm9wZW4oKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgdXBkYXRlUnVudGltZUNvbWJvKCkgewoJCUlSdW50aW1lVHlwZSBydW50aW1lVHlwZSA9IHNlcnZlci5nZXRTZXJ2ZXJUeXBlKCkuZ2V0UnVudGltZVR5cGUoKTsKCQlydW50aW1lcyA9IFNlcnZlclVJUGx1Z2luLmdldFJ1bnRpbWVzKHJ1bnRpbWVUeXBlKTsKCQkKCQlpZiAoU29ja2V0VXRpbC5pc0xvY2FsaG9zdChzZXJ2ZXIuZ2V0SG9zdCgpKSAmJiBydW50aW1lcyAhPSBudWxsKSB7CgkJCUxpc3QgcnVudGltZXMyID0gbmV3IEFycmF5TGlzdCgpOwoJCQlpbnQgc2l6ZSA9IHJ1bnRpbWVzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlSdW50aW1lIHJ1bnRpbWUyID0gcnVudGltZXNbaV07CgkJCQlpZiAoIXJ1bnRpbWUyLmlzU3R1YigpKQoJCQkJCXJ1bnRpbWVzMi5hZGQocnVudGltZTIpOwoJCQl9CgkJCXJ1bnRpbWVzID0gbmV3IElSdW50aW1lW3J1bnRpbWVzMi5zaXplKCldOwoJCQlydW50aW1lczIudG9BcnJheShydW50aW1lcyk7CgkJfQoJCQoJCWludCBzaXplID0gcnVudGltZXMubGVuZ3RoOwoJCVN0cmluZ1tdIGl0ZW1zID0gbmV3IFN0cmluZ1tzaXplXTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykKCQkJaXRlbXNbaV0gPSBydW50aW1lc1tpXS5nZXROYW1lKCk7CgkJCgkJcnVudGltZUNvbWJvLnNldEl0ZW1zKGl0ZW1zKTsKCX0KCglwcm90ZWN0ZWQgTGFiZWwgY3JlYXRlTGFiZWwoRm9ybVRvb2xraXQgdG9vbGtpdCwgQ29tcG9zaXRlIHBhcmVudCwgU3RyaW5nIHRleHQpIHsKCQlMYWJlbCBsYWJlbCA9IHRvb2xraXQuY3JlYXRlTGFiZWwocGFyZW50LCB0ZXh0KTsKCQlsYWJlbC5zZXRGb3JlZ3JvdW5kKHRvb2xraXQuZ2V0Q29sb3JzKCkuZ2V0Q29sb3IoRm9ybUNvbG9ycy5USVRMRSkpOwoJCXJldHVybiBsYWJlbDsKCX0KCQoJcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKCQlzdXBlci5kaXNwb3NlKCk7CgkJCgkJaWYgKHNlcnZlciAhPSBudWxsKQoJCQlzZXJ2ZXIucmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihsaXN0ZW5lcik7Cgl9CgoJLyogKG5vbi1KYXZhZG9jKQoJICogSW5pdGlhbGl6ZXMgdGhlIGVkaXRvciBwYXJ0IHdpdGggYSBzaXRlIGFuZCBpbnB1dC4KCSAqLwoJcHVibGljIHZvaWQgaW5pdChJRWRpdG9yU2l0ZSBzaXRlLCBJRWRpdG9ySW5wdXQgaW5wdXQpIHsKCQlzdXBlci5pbml0KHNpdGUsIGlucHV0KTsKCQkKCQlhZGRDaGFuZ2VMaXN0ZW5lcigpOwoJCWluaXRpYWxpemUoKTsKCX0KCQoJLyoqCgkgKiBJbml0aWFsaXplIHRoZSBmaWVsZHMgaW4gdGhpcyBlZGl0b3IuCgkgKi8KCXByb3RlY3RlZCB2b2lkIGluaXRpYWxpemUoKSB7CgkJaWYgKHNlcnZlck5hbWUgPT0gbnVsbCkKCQkJcmV0dXJuOwoJCXVwZGF0aW5nID0gdHJ1ZTsKCQkKCQlpZiAoc2VydmVyICE9IG51bGwpIHsKCQkJc2VydmVyTmFtZS5zZXRUZXh0KHNlcnZlci5nZXROYW1lKCkpOwoJCQlpZiAocmVhZE9ubHkpCgkJCQlzZXJ2ZXJOYW1lLnNldEVkaXRhYmxlKGZhbHNlKTsKCQkJZWxzZQoJCQkJc2VydmVyTmFtZS5zZXRFZGl0YWJsZSh0cnVlKTsKCQl9CgkJCgkJdXBkYXRpbmcgPSBmYWxzZTsKCX0KCQoJLy9wcm90ZWN0ZWQgdm9pZCB2YWxpZGF0ZSgpIHsgfQoKCS8qCgkgKiBAc2VlIElXb3JrYmVuY2hQYXJ0I3NldEZvY3VzKCkKCSAqLwoJcHVibGljIHZvaWQgc2V0Rm9jdXMoKSB7CgkJaWYgKHNlcnZlck5hbWUgIT0gbnVsbCkKCQkJc2VydmVyTmFtZS5zZXRGb2N1cygpOwoJCWVsc2UgaWYgKHNlcnZlckNvbmZpZ3VyYXRpb25OYW1lICE9IG51bGwpCgkJCXNlcnZlckNvbmZpZ3VyYXRpb25OYW1lLnNldEZvY3VzKCk7Cgl9Cn0=