LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWw7CgppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuUmVzb3VyY2VzUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5OdWxsUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5EaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLk1lc3NhZ2VEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLlByb2dyZXNzTW9uaXRvckRpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLm9wZXJhdGlvbi5JUnVubmFibGVXaXRoUHJvZ3Jlc3M7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5wcmVmZXJlbmNlLlByZWZlcmVuY2VQYWdlOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU2VsZWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU3RydWN0dXJlZFNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLndpbmRvdy5XaW5kb3c7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25BZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25FdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZERhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWRMYXlvdXQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5CdXR0b247CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db250cm9sOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGFiZWw7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5JV29ya2JlbmNoOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaFByZWZlcmVuY2VQYWdlOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuaGVscC5Xb3JrYmVuY2hIZWxwOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLlNlcnZlclVJQ29yZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwudGFzay5GaW5pc2hXaXphcmRGcmFnbWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwudGFzay5TYXZlUnVudGltZVRhc2s7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLnZpZXdlcnMuUnVudGltZUNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwud2l6YXJkLkNsb3NhYmxlV2l6YXJkRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC53aXphcmQuZnJhZ21lbnQuTmV3UnVudGltZVdpemFyZEZyYWdtZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS53aXphcmQuV2l6YXJkRnJhZ21lbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLndpemFyZC5UYXNrV2l6YXJkOwovKioKICogVGhlIHByZWZlcmVuY2UgcGFnZSB0aGF0IGhvbGRzIHNlcnZlciBydW50aW1lcy4KICovCnB1YmxpYyBjbGFzcyBSdW50aW1lUHJlZmVyZW5jZVBhZ2UgZXh0ZW5kcyBQcmVmZXJlbmNlUGFnZSBpbXBsZW1lbnRzIElXb3JrYmVuY2hQcmVmZXJlbmNlUGFnZSB7Cglwcm90ZWN0ZWQgQnV0dG9uIGVkaXQ7Cglwcm90ZWN0ZWQgQnV0dG9uIHJlbW92ZTsKCXByb3RlY3RlZCBMYWJlbCBwYXRoTGFiZWw7CgoJLyoqCgkgKiBSdW50aW1lUHJlZmVyZW5jZXNQYWdlIGNvbnN0cnVjdG9yIGNvbW1lbnQuCgkgKi8KCXB1YmxpYyBSdW50aW1lUHJlZmVyZW5jZVBhZ2UoKSB7CgkJc3VwZXIoKTsKCQlub0RlZmF1bHRBbmRBcHBseUJ1dHRvbigpOwoJfQoJCgkvKioKCSAqIENyZWF0ZSB0aGUgcHJlZmVyZW5jZSBvcHRpb25zLgoJICoKCSAqIEBwYXJhbSBwYXJlbnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbnRyb2wKCSAqLwoJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlQ29udGVudHMoQ29tcG9zaXRlIHBhcmVudCkgewoJCWluaXRpYWxpemVEaWFsb2dVbml0cyhwYXJlbnQpOwoJCQoJCUNvbXBvc2l0ZSBjb21wb3NpdGUgPSBuZXcgQ29tcG9zaXRlKHBhcmVudCwgU1dULk5PTkUpOwoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSBjb252ZXJ0SG9yaXpvbnRhbERMVXNUb1BpeGVscyg0KTsKCQlsYXlvdXQudmVydGljYWxTcGFjaW5nID0gY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKDQpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7CgkJbGF5b3V0Lm51bUNvbHVtbnMgPSAyOwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXQobGF5b3V0KTsKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0ZJTEwpOwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCVdvcmtiZW5jaEhlbHAuc2V0SGVscChjb21wb3NpdGUsIENvbnRleHRJZHMuUFJFRl9HRU5FUkFMKTsKCQkKCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChjb21wb3NpdGUsIFNXVC5XUkFQKTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJbGFiZWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlsYWJlbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZmVyZW5jZVJ1bnRpbWVzRGVzY3JpcHRpb24iKSk7CgkJCgkJZmluYWwgUnVudGltZUNvbXBvc2l0ZSBydW50aW1lQ29tcCA9IG5ldyBSdW50aW1lQ29tcG9zaXRlKGNvbXBvc2l0ZSwgU1dULk5PTkUsIG5ldyBSdW50aW1lQ29tcG9zaXRlLlJ1bnRpbWVTZWxlY3Rpb25MaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgcnVudGltZVNlbGVjdGVkKElSdW50aW1lIHJ1bnRpbWUpIHsKCQkJCWlmIChydW50aW1lID09IG51bGwpIHsKCQkJCQllZGl0LnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJCXJlbW92ZS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJCQlwYXRoTGFiZWwuc2V0VGV4dCgiIik7CgkJCQl9IGVsc2UgaWYgKHJ1bnRpbWUuaXNMb2NrZWQoKSkgewoJCQkJCWVkaXQuc2V0RW5hYmxlZChmYWxzZSk7CgkJCQkJcmVtb3ZlLnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJCXBhdGhMYWJlbC5zZXRUZXh0KHJ1bnRpbWUuZ2V0TG9jYXRpb24oKSArICIiKTsKCQkJCX0gZWxzZSB7CgkJCQkJZWRpdC5zZXRFbmFibGVkKHRydWUpOwoJCQkJCXJlbW92ZS5zZXRFbmFibGVkKHRydWUpOwoJCQkJCXBhdGhMYWJlbC5zZXRUZXh0KHJ1bnRpbWUuZ2V0TG9jYXRpb24oKSArICIiKTsKCQkJCX0KCQkJfQoJCX0pOwoJCXJ1bnRpbWVDb21wLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCB8IEdyaWREYXRhLkZJTExfVkVSVElDQUwpKTsKCQkKCQlDb21wb3NpdGUgYnV0dG9uQ29tcCA9IG5ldyBDb21wb3NpdGUoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSAwOwoJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSBjb252ZXJ0VmVydGljYWxETFVzVG9QaXhlbHMoNCk7CgkJbGF5b3V0Lm1hcmdpbldpZHRoID0gMDsKCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gMDsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDE7CgkJYnV0dG9uQ29tcC5zZXRMYXlvdXQobGF5b3V0KTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0ZJTEwpOwoJCWJ1dHRvbkNvbXAuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlCdXR0b24gYWRkID0gU1dUVXRpbC5jcmVhdGVCdXR0b24oYnV0dG9uQ29tcCwgU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhZGQiKSk7CgkJYWRkLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlpZiAoc2hvd1dpemFyZChudWxsKSA9PSBXaW5kb3cuQ0FOQ0VMKQoJCQkJCXJldHVybjsKCQkJCXJ1bnRpbWVDb21wLnJlZnJlc2goKTsKCQkJfQoJCX0pOwoJCQoJCWVkaXQgPSBTV1RVdGlsLmNyZWF0ZUJ1dHRvbihidXR0b25Db21wLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWVkaXQiKSk7CgkJZWRpdC5zZXRFbmFibGVkKGZhbHNlKTsKCQllZGl0LmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlJUnVudGltZSBydW50aW1lID0gcnVudGltZUNvbXAuZ2V0U2VsZWN0ZWRSdW50aW1lKCk7CgkJCQlpZiAocnVudGltZSAhPSBudWxsKSB7CgkJCQkJSVJ1bnRpbWVXb3JraW5nQ29weSBydW50aW1lV29ya2luZ0NvcHkgPSBydW50aW1lLmNyZWF0ZVdvcmtpbmdDb3B5KCk7CgkJCQkJaWYgKHNob3dXaXphcmQocnVudGltZVdvcmtpbmdDb3B5KSAhPSBXaW5kb3cuQ0FOQ0VMKSB7CgkJCQkJCXRyeSB7CgkJCQkJCQlydW50aW1lV29ya2luZ0NvcHkuc2F2ZShmYWxzZSwgbmV3IE51bGxQcm9ncmVzc01vbml0b3IoKSk7CgkJCQkJCQlydW50aW1lQ29tcC5yZWZyZXNoKHJ1bnRpbWUpOwoJCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKCQkJCQkJCS8vIGlnbm9yZQoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9CgkJfSk7CgkJCgkJcmVtb3ZlID0gU1dUVXRpbC5jcmVhdGVCdXR0b24oYnV0dG9uQ29tcCwgU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVyZW1vdmUiKSk7CgkJcmVtb3ZlLnNldEVuYWJsZWQoZmFsc2UpOwoJCXJlbW92ZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJSVJ1bnRpbWUgcnVudGltZSA9IHJ1bnRpbWVDb21wLmdldFNlbGVjdGVkUnVudGltZSgpOwoJCQkJaWYgKHNob3VsZFJlbW92ZVJ1bnRpbWUocnVudGltZSkpCgkJCQkJdHJ5IHsKCQkJCQkJcnVudGltZS5kZWxldGUoKTsKCQkJCQkJcnVudGltZUNvbXAucmVtb3ZlKHJ1bnRpbWUpOwoJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewoJCQkJCQkvLyBpZ25vcmUKCQkJCQl9CgkJCX0KCQl9KTsKCQkKCQlCdXR0b24gc2VhcmNoID0gU1dUVXRpbC5jcmVhdGVCdXR0b24oYnV0dG9uQ29tcCwgU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVzZWFyY2giKSk7CgkJc2VhcmNoLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQl0cnkgewoJCQkJCWZpbmFsIFByb2dyZXNzTW9uaXRvckRpYWxvZyBkaWFsb2cgPSBuZXcgUHJvZ3Jlc3NNb25pdG9yRGlhbG9nKGdldFNoZWxsKCkpOwoJCQkJCWRpYWxvZy5zZXRCbG9ja09uT3BlbihmYWxzZSk7CgkJCQkJZGlhbG9nLnNldENhbmNlbGFibGUodHJ1ZSk7CgkJCQkJZGlhbG9nLm9wZW4oKTsKCQkJCQlmaW5hbCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IgPSBkaWFsb2cuZ2V0UHJvZ3Jlc3NNb25pdG9yKCk7CgkJCQkJZmluYWwgSVJ1bnRpbWVMb2NhdG9yW10gbG9jYXRvcnMgPSBTZXJ2ZXJDb3JlLmdldFJ1bnRpbWVMb2NhdG9ycygpOwoJCQkJCW1vbml0b3IuYmVnaW5UYXNrKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlc2VhcmNoIiksIDEwMCAqIGxvY2F0b3JzLmxlbmd0aCArIDEwKTsKCQkJCQlmaW5hbCBMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCQkJCgkJCQkJZmluYWwgSVJ1bnRpbWVMb2NhdG9yLlJ1bnRpbWVTZWFyY2hMaXN0ZW5lciBsaXN0ZW5lciA9IG5ldyBJUnVudGltZUxvY2F0b3IuUnVudGltZVNlYXJjaExpc3RlbmVyKCkgewoJCQkJCQlwdWJsaWMgdm9pZCBydW50aW1lRm91bmQoZmluYWwgSVJ1bnRpbWVXb3JraW5nQ29weSBydW50aW1lKSB7CgkJCQkJCQlkaWFsb2cuZ2V0U2hlbGwoKS5nZXREaXNwbGF5KCkuc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoJCQkJCQkJCXB1YmxpYyB2b2lkIHJ1bigpIHsKCQkJCQkJCQkJbW9uaXRvci5zdWJUYXNrKHJ1bnRpbWUuZ2V0TmFtZSgpKTsKCQkJCQkJCQl9CgkJCQkJCQl9KTsKCQkJCQkJCWxpc3QuYWRkKHJ1bnRpbWUpOwoJCQkJCQl9CgkJCQkJfTsKCQkJCQkKCQkJCQlJUnVubmFibGVXaXRoUHJvZ3Jlc3MgcnVubmFibGUgPSBuZXcgSVJ1bm5hYmxlV2l0aFByb2dyZXNzKCkgewoJCQkJCQlwdWJsaWMgdm9pZCBydW4oSVByb2dyZXNzTW9uaXRvciBtb25pdG9yMikgewoJCQkJCQkJaWYgKGxvY2F0b3JzICE9IG51bGwpIHsKCQkJCQkJCQlpbnQgc2l6ZSA9IGxvY2F0b3JzLmxlbmd0aDsKCQkJCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJCQkJCQlpZiAoIW1vbml0b3IyLmlzQ2FuY2VsZWQoKSkKCQkJCQkJCQkJCXRyeSB7CgkJCQkJCQkJCQkJbG9jYXRvcnNbaV0uc2VhcmNoRm9yUnVudGltZXMobnVsbCwgbGlzdGVuZXIsIG1vbml0b3IyKTsKCQkJCQkJCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCQkJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiRXJyb3IgbG9jYXRpbmcgcnVudGltZXM6ICIgKyBsb2NhdG9yc1tpXS5nZXRJZCgpLCBjZSk7CgkJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQkJVHJhY2UudHJhY2UoVHJhY2UuSU5GTywgIkRvbmUgc2VhcmNoIik7CgkJCQkJCX0KCQkJCQl9OwoJCQkJCWRpYWxvZy5ydW4odHJ1ZSwgdHJ1ZSwgcnVubmFibGUpOwoJCQkJCQoJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVSLCAiRm91bmQgcnVudGltZXM6ICIgKyBsaXN0LnNpemUoKSk7CgkJCQkJCgkJCQkJaWYgKCFtb25pdG9yLmlzQ2FuY2VsZWQoKSkgewoJCQkJCQlpZiAobGlzdC5pc0VtcHR5KCkpIHsKCQkJCQkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihnZXRTaGVsbCgpLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWluZm9Ob1J1bnRpbWVzRm91bmQiKSk7CgkJCQkJCQlyZXR1cm47CgkJCQkJCX0KCQkJCQkJbW9uaXRvci53b3JrZWQoNSk7CgkJCQkJCS8vIHJlbW92ZSBkdXBsaWNhdGVzIGZyb20gbGlzdCAoYmFzZWQgb24gbG9jYXRpb24pCgkJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVSLCAiUmVtb3ZpbmcgZHVwbGljYXRlcyIpOwoJCQkJCQlMaXN0IGdvb2QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCQkJCUl0ZXJhdG9yIGl0ZXJhdG9yMiA9IGxpc3QuaXRlcmF0b3IoKTsKCQkJCQkJd2hpbGUgKGl0ZXJhdG9yMi5oYXNOZXh0KCkpIHsKCQkJCQkJCWJvb2xlYW4gZHVwID0gZmFsc2U7CgkJCQkJCQlJUnVudGltZSB3YyA9IChJUnVudGltZSkgaXRlcmF0b3IyLm5leHQoKTsKCQkJCQkJCQoJCQkJCQkJSVJ1bnRpbWVbXSBydW50aW1lcyA9IFNlcnZlckNvcmUuZ2V0UnVudGltZXMoKTsKCQkJCQkJCWlmIChydW50aW1lcyAhPSBudWxsKSB7CgkJCQkJCQkJaW50IHNpemUgPSBydW50aW1lcy5sZW5ndGg7CgkJCQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQkJCQkJaWYgKHJ1bnRpbWVzW2ldLmdldExvY2F0aW9uKCkuZXF1YWxzKHdjLmdldExvY2F0aW9uKCkpKQoJCQkJCQkJCQkJZHVwID0gdHJ1ZTsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCQlpZiAoIWR1cCkKCQkJCQkJCQlnb29kLmFkZCh3Yyk7CgkJCQkJCX0KCQkJCQkJbW9uaXRvci53b3JrZWQoNSk7CgkJCQkJCQoJCQkJCQkvLyBhZGQgdG8gbGlzdAoJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FUiwgIkFkZGluZyBydW50aW1lczogIiArIGdvb2Quc2l6ZSgpKTsKCQkJCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBnb29kLml0ZXJhdG9yKCk7CgkJCQkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCQkJCUlSdW50aW1lV29ya2luZ0NvcHkgd2MgPSAoSVJ1bnRpbWVXb3JraW5nQ29weSkgaXRlcmF0b3IubmV4dCgpOwoJCQkJCQkJd2Muc2F2ZShmYWxzZSwgbW9uaXRvcik7CgkJCQkJCX0KCQkJCQkJbW9uaXRvci5kb25lKCk7CgkJCQkJfQoJCQkJCWRpYWxvZy5jbG9zZSgpOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgZmluZGluZyBydW50aW1lcyIsIGV4KTsKCQkJCX0KCQkJCXJ1bnRpbWVDb21wLnJlZnJlc2goKTsKCQkJfQoJCX0pOwoJCQoJCXBhdGhMYWJlbCA9IG5ldyBMYWJlbChwYXJlbnQsIFNXVC5OT05FKTsKCQlwYXRoTGFiZWwuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKSk7CgkJCgkJRGlhbG9nLmFwcGx5RGlhbG9nRm9udChjb21wb3NpdGUpOwoJCgkJcmV0dXJuIGNvbXBvc2l0ZTsKCX0KCQoJcHJvdGVjdGVkIGJvb2xlYW4gc2hvdWxkUmVtb3ZlUnVudGltZShJUnVudGltZSBydW50aW1lKSB7CgkJaWYgKHJ1bnRpbWUgPT0gbnVsbCkKCQkJcmV0dXJuIGZhbHNlOwoKCQkvLyBjaGVjayBmb3IgdXNlCgkJYm9vbGVhbiBpblVzZSA9IGZhbHNlOwoJCgkJSVNlcnZlcltdIHNlcnZlcnMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlcnMoKTsKCQlpZiAoc2VydmVycyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gc2VydmVycy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlpZiAocnVudGltZS5lcXVhbHMoc2VydmVyc1tpXS5nZXRSdW50aW1lKCkpKQoJCQkJCWluVXNlID0gdHJ1ZTsKCQkJfQoJCX0KCQkKCQlJUHJvamVjdFtdIHByb2plY3RzID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKS5nZXRQcm9qZWN0cygpOwoJCWlmIChwcm9qZWN0cyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gcHJvamVjdHMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSVByb2plY3RQcm9wZXJ0aWVzIHByb3BzID0gU2VydmVyQ29yZS5nZXRQcm9qZWN0UHJvcGVydGllcyhwcm9qZWN0c1tpXSk7CgkJCQlpZiAocnVudGltZS5lcXVhbHMocHJvcHMuZ2V0UnVudGltZVRhcmdldCgpKSkKCQkJCQlpblVzZSA9IHRydWU7CgkJCX0KCQl9CgkJCgkJaWYgKGluVXNlKSB7CgkJCWlmICghTWVzc2FnZURpYWxvZy5vcGVuQ29uZmlybShnZXRTaGVsbCgpLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWRlZmF1bHREaWFsb2dUaXRsZSIpLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWRpYWxvZ1J1bnRpbWVJblVzZSIpKSkKCQkJCXJldHVybiBmYWxzZTsKCQl9CgkJCgkJcmV0dXJuIHRydWU7Cgl9CgkKCXByb3RlY3RlZCBpbnQgc2hvd1dpemFyZChmaW5hbCBJUnVudGltZVdvcmtpbmdDb3B5IHJ1bnRpbWVXb3JraW5nQ29weSkgewoJCVN0cmluZyB0aXRsZSA9IG51bGw7CgkJV2l6YXJkRnJhZ21lbnQgZnJhZ21lbnQgPSBudWxsOwoJCWlmIChydW50aW1lV29ya2luZ0NvcHkgPT0gbnVsbCkgewoJCQl0aXRsZSA9IFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6TmV3UnVudGltZVdpemFyZFRpdGxlIik7CgkJCWZyYWdtZW50ID0gbmV3IFdpemFyZEZyYWdtZW50KCkgewoJCQkJcHJvdGVjdGVkIHZvaWQgY3JlYXRlQ2hpbGRGcmFnbWVudHMoTGlzdCBsaXN0KSB7CgkJCQkJbGlzdC5hZGQobmV3IE5ld1J1bnRpbWVXaXphcmRGcmFnbWVudCgpKTsKCQkJCQlsaXN0LmFkZChuZXcgRmluaXNoV2l6YXJkRnJhZ21lbnQobmV3IFNhdmVSdW50aW1lVGFzaygpKSk7CgkJCQl9CgkJCX07CgkJfSBlbHNlIHsKCQkJdGl0bGUgPSBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpekVkaXRSdW50aW1lV2l6YXJkVGl0bGUiKTsKCQkJZmluYWwgV2l6YXJkRnJhZ21lbnQgZnJhZ21lbnQyID0gU2VydmVyVUlDb3JlLmdldFdpemFyZEZyYWdtZW50KHJ1bnRpbWVXb3JraW5nQ29weS5nZXRSdW50aW1lVHlwZSgpLmdldElkKCkpOwoJCQlpZiAoZnJhZ21lbnQyID09IG51bGwpIHsKCQkJCWVkaXQuc2V0RW5hYmxlZChmYWxzZSk7CgkJCQlyZXR1cm4gV2luZG93LkNBTkNFTDsKCQkJfQoJCQlmcmFnbWVudCA9IG5ldyBXaXphcmRGcmFnbWVudCgpIHsKCQkJCXByb3RlY3RlZCB2b2lkIGNyZWF0ZUNoaWxkRnJhZ21lbnRzKExpc3QgbGlzdCkgewoJCQkJCWxpc3QuYWRkKG5ldyBXaXphcmRGcmFnbWVudCgpIHsKCQkJCQkJcHVibGljIHZvaWQgZW50ZXIoKSB7CgkJCQkJCQlnZXRUYXNrTW9kZWwoKS5wdXRPYmplY3QoSVRhc2tNb2RlbC5UQVNLX1JVTlRJTUUsIHJ1bnRpbWVXb3JraW5nQ29weSk7CgkJCQkJCX0KCQkJCQl9KTsKCQkJCQlsaXN0LmFkZChmcmFnbWVudDIpOwoJCQkJCWxpc3QuYWRkKG5ldyBGaW5pc2hXaXphcmRGcmFnbWVudChuZXcgU2F2ZVJ1bnRpbWVUYXNrKCkpKTsKCQkJCX0KCQkJfTsKCQl9CgkJVGFza1dpemFyZCB3aXphcmQgPSBuZXcgVGFza1dpemFyZCh0aXRsZSwgZnJhZ21lbnQpOwoJCXdpemFyZC5zZXRGb3JjZVByZXZpb3VzQW5kTmV4dEJ1dHRvbnModHJ1ZSk7CgkJQ2xvc2FibGVXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IENsb3NhYmxlV2l6YXJkRGlhbG9nKGdldFNoZWxsKCksIHdpemFyZCk7CgkJcmV0dXJuIGRpYWxvZy5vcGVuKCk7Cgl9CgkKCXByb3RlY3RlZCBJUnVudGltZSBnZXRTZWxlY3Rpb24oSVNlbGVjdGlvbiBzZWwyKSB7CgkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBzZWwyOwoJCXJldHVybiAoSVJ1bnRpbWUpIHNlbC5nZXRGaXJzdEVsZW1lbnQoKTsKCX0KCQoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGlzIHByZWZlcmVuY2UgcGFnZSB1c2luZyB0aGUgcGFzc2VkIGRlc2t0b3AuCgkgKgoJICogQHBhcmFtIGRlc2t0b3AgdGhlIGN1cnJlbnQgZGVza3RvcAoJICovCglwdWJsaWMgdm9pZCBpbml0KElXb3JrYmVuY2ggd29ya2JlbmNoKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogUGVyZm9ybXMgc3BlY2lhbCBwcm9jZXNzaW5nIHdoZW4gdGhpcyBwYWdlJ3MgRGVmYXVsdHMgYnV0dG9uIGhhcyBiZWVuIHByZXNzZWQuCgkgKiA8cD4KCSAqIFRoaXMgaXMgYSBmcmFtZXdvcmsgaG9vayBtZXRob2QgZm9yIHN1YmxjYXNzZXMgdG8gZG8gc3BlY2lhbCB0aGluZ3Mgd2hlbgoJICogdGhlIERlZmF1bHRzIGJ1dHRvbiBoYXMgYmVlbiBwcmVzc2VkLgoJICogU3ViY2xhc3NlcyBtYXkgb3ZlcnJpZGUsIGJ1dCBzaG91bGQgY2FsbCA8Y29kZT5zdXBlci5wZXJmb3JtRGVmYXVsdHM8L2NvZGU+LgoJICogPC9wPgoJICovCglwcm90ZWN0ZWQgdm9pZCBwZXJmb3JtRGVmYXVsdHMoKSB7CgkJc3VwZXIucGVyZm9ybURlZmF1bHRzKCk7Cgl9CgoJLyoqIAoJICogTWV0aG9kIGRlY2xhcmVkIG9uIElQcmVmZXJlbmNlUGFnZS4KCSAqIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlCgkgKi8KCXB1YmxpYyBib29sZWFuIHBlcmZvcm1PaygpIHsKCQkvLyBUT0RPIC0gc2hvdWxkIG5vdCBzYXZlIHVudGlsIHVzZXIgaGl0cyBvayAKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXRWaXNpYmxlKGJvb2xlYW4gdmlzaWJsZSkgewoJCXN1cGVyLnNldFZpc2libGUodmlzaWJsZSk7CgkJaWYgKHZpc2libGUpCgkJCXNldFRpdGxlKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZmVyZW5jZVJ1bnRpbWVzVGl0bGVMb25nIikpOwoJfQp9