LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWw7CgppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5EaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5wcmVmZXJlbmNlLlByZWZlcmVuY2VQYWdlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyQ29yZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXJQcmVmZXJlbmNlczsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkJ1dHRvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbnRyb2w7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Hcm91cDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU3Bpbm5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklXb3JrYmVuY2g7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5JV29ya2JlbmNoUHJlZmVyZW5jZVBhZ2U7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5QbGF0Zm9ybVVJOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuaGVscC5JV29ya2JlbmNoSGVscFN5c3RlbTsKLyoqCiAqIFRoZSBwcmVmZXJlbmNlIHBhZ2UgdGhhdCBob2xkcyBzZXJ2ZXIgcHJvcGVydGllcy4KICovCnB1YmxpYyBjbGFzcyBTZXJ2ZXJQcmVmZXJlbmNlUGFnZSBleHRlbmRzIFByZWZlcmVuY2VQYWdlIGltcGxlbWVudHMgSVdvcmtiZW5jaFByZWZlcmVuY2VQYWdlIHsKCXByb3RlY3RlZCBCdXR0b24gcHVibGlzaEJlZm9yZVN0YXJ0OwoJcHJvdGVjdGVkIEJ1dHRvbiBhdXRvUmVzdGFydDsKCglwcm90ZWN0ZWQgQnV0dG9uIHByb21wdElycmV2ZXJzaWJsZTsKCQoJcHJvdGVjdGVkIEJ1dHRvbiBzaG93T25BY3Rpdml0eTsKCQoJcHJvdGVjdGVkIGJ5dGUgc2F2ZUVkaXRvcnM7CgkKCXByb3RlY3RlZCBCdXR0b24gc2F2ZU5ldmVyOwoJcHJvdGVjdGVkIEJ1dHRvbiBzYXZlUHJvbXB0OwoJcHJvdGVjdGVkIEJ1dHRvbiBzYXZlQXV0bzsKCQoJcHJvdGVjdGVkIEJ1dHRvbiBjcmVhdGVJbldvcmtzcGFjZTsKCglwcm90ZWN0ZWQgU2VydmVyUHJlZmVyZW5jZXMgcHJlZmVyZW5jZXM7Cglwcm90ZWN0ZWQgU2VydmVyVUlQcmVmZXJlbmNlcyB1aVByZWZlcmVuY2VzOwoJCglwcm90ZWN0ZWQgQnV0dG9uIGF1dG9QdWJsaXNoT25BY3Rpb247Cglwcm90ZWN0ZWQgQnV0dG9uIGF1dG9QdWJsaXNoTG9jYWw7Cglwcm90ZWN0ZWQgU3Bpbm5lciBhdXRvUHVibGlzaExvY2FsVGltZTsKCXByb3RlY3RlZCBCdXR0b24gYXV0b1B1Ymxpc2hSZW1vdGU7Cglwcm90ZWN0ZWQgU3Bpbm5lciBhdXRvUHVibGlzaFJlbW90ZVRpbWU7CgoJLyoqCgkgKiBTZXJ2ZXJQcmVmZXJlbmNlc1BhZ2UgY29uc3RydWN0b3IgY29tbWVudC4KCSAqLwoJcHVibGljIFNlcnZlclByZWZlcmVuY2VQYWdlKCkgewoJCXN1cGVyKCk7CgkKCQlwcmVmZXJlbmNlcyA9IFNlcnZlclByZWZlcmVuY2VzLmdldEluc3RhbmNlKCk7CgkJdWlQcmVmZXJlbmNlcyA9IFNlcnZlclVJUGx1Z2luLmdldFByZWZlcmVuY2VzKCk7Cgl9CgkKCS8qKgoJICogQ3JlYXRlIHRoZSBwcmVmZXJlbmNlIG9wdGlvbnMuCgkgKgoJICogQHBhcmFtIHBhcmVudCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGUKCSAqIEByZXR1cm4gb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29udHJvbAoJICovCglwcm90ZWN0ZWQgQ29udHJvbCBjcmVhdGVDb250ZW50cyhDb21wb3NpdGUgcGFyZW50KSB7CgkJaW5pdGlhbGl6ZURpYWxvZ1VuaXRzKHBhcmVudCk7CgkJCgkJQ29tcG9zaXRlIGNvbXBvc2l0ZSA9IG5ldyBDb21wb3NpdGUocGFyZW50LCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5ob3Jpem9udGFsU3BhY2luZyA9IGNvbnZlcnRIb3Jpem9udGFsRExVc1RvUGl4ZWxzKDQpOwoJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSBjb252ZXJ0VmVydGljYWxETFVzVG9QaXhlbHMoNCk7CgkJbGF5b3V0Lm1hcmdpbldpZHRoID0gMDsKCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gMDsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDM7CgkJY29tcG9zaXRlLnNldExheW91dChsYXlvdXQpOwoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMIHwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fRklMTCk7CgkJY29tcG9zaXRlLnNldExheW91dERhdGEoZGF0YSk7CgkJSVdvcmtiZW5jaEhlbHBTeXN0ZW0gd2hzID0gUGxhdGZvcm1VSS5nZXRXb3JrYmVuY2goKS5nZXRIZWxwU3lzdGVtKCk7CgkJd2hzLnNldEhlbHAoY29tcG9zaXRlLCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTCk7CgkJCgkJcHVibGlzaEJlZm9yZVN0YXJ0ID0gbmV3IEJ1dHRvbihjb21wb3NpdGUsIFNXVC5DSEVDSyk7CgkJcHVibGlzaEJlZm9yZVN0YXJ0LnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmQXV0b1B1Ymxpc2giKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCXB1Ymxpc2hCZWZvcmVTdGFydC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCXB1Ymxpc2hCZWZvcmVTdGFydC5zZXRTZWxlY3Rpb24ocHJlZmVyZW5jZXMuaXNBdXRvUHVibGlzaGluZygpKTsKCQl3aHMuc2V0SGVscChwdWJsaXNoQmVmb3JlU3RhcnQsIENvbnRleHRJZHMuUFJFRl9HRU5FUkFMX1BVQkxJU0hfQkVGT1JFX1NUQVJUKTsKCQkKCQlhdXRvUHVibGlzaExvY2FsID0gbmV3IEJ1dHRvbihjb21wb3NpdGUsIFNXVC5DSEVDSyk7CgkJYXV0b1B1Ymxpc2hMb2NhbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZkF1dG9QdWJsaXNoTG9jYWwiKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAxOwoJCWF1dG9QdWJsaXNoTG9jYWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlhdXRvUHVibGlzaExvY2FsLnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5nZXRBdXRvUHVibGlzaExvY2FsKCkpOwoJCS8vV29ya2JlbmNoSGVscC5zZXRIZWxwKHNhdmVQcm9tcHQsIENvbnRleHRJZHMuKTsKCQkKCQlhdXRvUHVibGlzaExvY2FsVGltZSA9IG5ldyBTcGlubmVyKGNvbXBvc2l0ZSwgU1dULkJPUkRFUik7CgkJYXV0b1B1Ymxpc2hMb2NhbFRpbWUuc2V0TWluaW11bSgwKTsKCQlhdXRvUHVibGlzaExvY2FsVGltZS5zZXRNYXhpbXVtKDEyMCk7CgkJYXV0b1B1Ymxpc2hMb2NhbFRpbWUuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmdldEF1dG9QdWJsaXNoTG9jYWxUaW1lKCkpOwoJCWF1dG9QdWJsaXNoTG9jYWxUaW1lLnNldEVuYWJsZWQoYXV0b1B1Ymxpc2hMb2NhbC5nZXRTZWxlY3Rpb24oKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0VORCk7CgkJZGF0YS53aWR0aEhpbnQgPSA3NTsKCQlhdXRvUHVibGlzaExvY2FsVGltZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCUxhYmVsIGxhYmVsID0gbmV3IExhYmVsKGNvbXBvc2l0ZSwgU1dULk5PTkUpOwoJCWxhYmVsLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmQXV0b1B1Ymxpc2hTZWNvbmRzIikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9FTkQpOwoJCWxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJYXV0b1B1Ymxpc2hMb2NhbC5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJYXV0b1B1Ymxpc2hMb2NhbFRpbWUuc2V0RW5hYmxlZChhdXRvUHVibGlzaExvY2FsLmdldFNlbGVjdGlvbigpKTsKCQkJfQoJCX0pOwoJCQoJCWF1dG9QdWJsaXNoUmVtb3RlID0gbmV3IEJ1dHRvbihjb21wb3NpdGUsIFNXVC5DSEVDSyk7CgkJYXV0b1B1Ymxpc2hSZW1vdGUuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXByZWZBdXRvUHVibGlzaFJlbW90ZSIpKTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDE7CgkJYXV0b1B1Ymxpc2hSZW1vdGUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlhdXRvUHVibGlzaFJlbW90ZS5zZXRTZWxlY3Rpb24ocHJlZmVyZW5jZXMuZ2V0QXV0b1B1Ymxpc2hSZW1vdGUoKSk7CgkJLy9Xb3JrYmVuY2hIZWxwLnNldEhlbHAoYXV0b1B1Ymxpc2hSZW1vdGUsIENvbnRleHRJZHMuKTsKCQkKCQlhdXRvUHVibGlzaFJlbW90ZVRpbWUgPSBuZXcgU3Bpbm5lcihjb21wb3NpdGUsIFNXVC5CT1JERVIpOwoJCWF1dG9QdWJsaXNoTG9jYWxUaW1lLnNldE1pbmltdW0oMCk7CgkJYXV0b1B1Ymxpc2hMb2NhbFRpbWUuc2V0TWF4aW11bSgxMjApOwoJCWF1dG9QdWJsaXNoUmVtb3RlVGltZS5zZXRTZWxlY3Rpb24ocHJlZmVyZW5jZXMuZ2V0QXV0b1B1Ymxpc2hSZW1vdGVUaW1lKCkpOwoJCWF1dG9QdWJsaXNoUmVtb3RlVGltZS5zZXRFbmFibGVkKGF1dG9QdWJsaXNoUmVtb3RlLmdldFNlbGVjdGlvbigpKTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCk7CgkJZGF0YS53aWR0aEhpbnQgPSA3NTsKCQlhdXRvUHVibGlzaFJlbW90ZVRpbWUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlhdXRvUHVibGlzaFJlbW90ZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJYXV0b1B1Ymxpc2hSZW1vdGVUaW1lLnNldEVuYWJsZWQoYXV0b1B1Ymxpc2hSZW1vdGUuZ2V0U2VsZWN0aW9uKCkpOwoJCQl9CgkJfSk7CgkJCgkJbGFiZWwgPSBuZXcgTGFiZWwoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJbGFiZWwuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXByZWZBdXRvUHVibGlzaFNlY29uZHMiKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0VORCk7CgkJbGFiZWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlhdXRvUmVzdGFydCA9IG5ldyBCdXR0b24oY29tcG9zaXRlLCBTV1QuQ0hFQ0spOwoJCWF1dG9SZXN0YXJ0LnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmQXV0b1Jlc3RhcnQiKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCWF1dG9SZXN0YXJ0LnNldExheW91dERhdGEoZGF0YSk7CgkJYXV0b1Jlc3RhcnQuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmlzQXV0b1Jlc3RhcnRpbmcoKSk7CgkJd2hzLnNldEhlbHAoYXV0b1Jlc3RhcnQsIENvbnRleHRJZHMuUFJFRl9HRU5FUkFMX0FVVE9fUkVTVEFSVCk7CgkJCgkJcHJvbXB0SXJyZXZlcnNpYmxlID0gbmV3IEJ1dHRvbihjb21wb3NpdGUsIFNXVC5DSEVDSyk7CgkJcHJvbXB0SXJyZXZlcnNpYmxlLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmUHJvbXB0SXJyZXZlcnNpYmxlIikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQlwcm9tcHRJcnJldmVyc2libGUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlwcm9tcHRJcnJldmVyc2libGUuc2V0U2VsZWN0aW9uKHVpUHJlZmVyZW5jZXMuZ2V0UHJvbXB0QmVmb3JlSXJyZXZlcnNpYmxlQ2hhbmdlKCkpOwoJCXdocy5zZXRIZWxwKHByb21wdElycmV2ZXJzaWJsZSwgQ29udGV4dElkcy5QUkVGX0dFTkVSQUxfUFJPTVBUX0lSUkVWRVJTSUJMRSk7CgkJCgkJc2hvd09uQWN0aXZpdHkgPSBuZXcgQnV0dG9uKGNvbXBvc2l0ZSwgU1dULkNIRUNLKTsKCQlzaG93T25BY3Rpdml0eS5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZlNob3dPbkFjdGl2aXR5IikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQlzaG93T25BY3Rpdml0eS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCXNob3dPbkFjdGl2aXR5LnNldFNlbGVjdGlvbih1aVByZWZlcmVuY2VzLmdldFNob3dPbkFjdGl2aXR5KCkpOwoJCXdocy5zZXRIZWxwKHNob3dPbkFjdGl2aXR5LCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTF9TSE9XX09OX0FDVElWSVRZKTsKCQkKCQljcmVhdGVJbldvcmtzcGFjZSA9IG5ldyBCdXR0b24oY29tcG9zaXRlLCBTV1QuQ0hFQ0spOwoJCWNyZWF0ZUluV29ya3NwYWNlLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmQ3JlYXRlSW5Xb3Jrc3BhY2UiKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCWNyZWF0ZUluV29ya3NwYWNlLnNldExheW91dERhdGEoZGF0YSk7CgkJY3JlYXRlSW5Xb3Jrc3BhY2Uuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmlzQ3JlYXRlUmVzb3VyY2VzSW5Xb3Jrc3BhY2UoKSk7CgkJd2hzLnNldEhlbHAoY3JlYXRlSW5Xb3Jrc3BhY2UsIENvbnRleHRJZHMuUFJFRl9HRU5FUkFMX0NSRUFURV9JTl9XT1JLU1BBQ0UpOwoJCQoJCS8vIHNhdmUgZWRpdG9ycyBncm91cAoJCUdyb3VwIHNhdmVFZGl0b3JHcm91cCA9IG5ldyBHcm91cChjb21wb3NpdGUsIFNXVC5OT05FKTsKCQlzYXZlRWRpdG9yR3JvdXAuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXByZWZTYXZlRWRpdG9yc0dyb3VwIikpOwoJCQoJCWxheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJbGF5b3V0Lm51bUNvbHVtbnMgPSAzOwoJCXNhdmVFZGl0b3JHcm91cC5zZXRMYXlvdXQobGF5b3V0KTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJc2F2ZUVkaXRvckdyb3VwLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJc2F2ZU5ldmVyID0gbmV3IEJ1dHRvbihzYXZlRWRpdG9yR3JvdXAsIFNXVC5SQURJTyk7CgkJc2F2ZU5ldmVyLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmU2F2ZUVkaXRvcnNOZXZlciIpKTsKCQlzYXZlTmV2ZXIuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlzYXZlRWRpdG9ycyA9IFNlcnZlclVJUHJlZmVyZW5jZXMuU0FWRV9FRElUT1JTX05FVkVSOwoJCQl9CgkJfSk7CgkJd2hzLnNldEhlbHAoc2F2ZU5ldmVyLCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTF9TQVZFX0VESVRPUlMpOwoJCQoJCXNhdmVQcm9tcHQgPSBuZXcgQnV0dG9uKHNhdmVFZGl0b3JHcm91cCwgU1dULlJBRElPKTsKCQlzYXZlUHJvbXB0LnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmU2F2ZUVkaXRvcnNQcm9tcHQiKSk7CgkJc2F2ZVByb21wdC5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZXZlbnQpIHsKCQkJCXNhdmVFZGl0b3JzID0gU2VydmVyVUlQcmVmZXJlbmNlcy5TQVZFX0VESVRPUlNfUFJPTVBUOwoJCQl9CgkJfSk7CgkJd2hzLnNldEhlbHAoc2F2ZVByb21wdCwgQ29udGV4dElkcy5QUkVGX0dFTkVSQUxfU0FWRV9FRElUT1JTKTsKCQkKCQlzYXZlQXV0byA9IG5ldyBCdXR0b24oc2F2ZUVkaXRvckdyb3VwLCBTV1QuUkFESU8pOwoJCXNhdmVBdXRvLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmU2F2ZUVkaXRvcnNBdXRvc2F2ZSIpKTsKCQlzYXZlQXV0by5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZXZlbnQpIHsKCQkJCXNhdmVFZGl0b3JzID0gU2VydmVyVUlQcmVmZXJlbmNlcy5TQVZFX0VESVRPUlNfQVVUTzsKCQkJfQoJCX0pOwoJCXdocy5zZXRIZWxwKHNhdmVBdXRvLCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTF9TQVZFX0VESVRPUlMpOwoJCQoJCXNldFNhdmVFZGl0b3JTdGF0dXModWlQcmVmZXJlbmNlcy5nZXRTYXZlRWRpdG9ycygpKTsKCQkKCQlEaWFsb2cuYXBwbHlEaWFsb2dGb250KGNvbXBvc2l0ZSk7CgkKCQlyZXR1cm4gY29tcG9zaXRlOwoJfQoJCglwcm90ZWN0ZWQgdm9pZCBzZXRTYXZlRWRpdG9yU3RhdHVzKGJ5dGUgc3RhdHVzKSB7CgkJc2F2ZUVkaXRvcnMgPSBzdGF0dXM7CgkJc2F2ZU5ldmVyLnNldFNlbGVjdGlvbihzYXZlRWRpdG9ycyA9PSBTZXJ2ZXJVSVByZWZlcmVuY2VzLlNBVkVfRURJVE9SU19ORVZFUik7CgkJc2F2ZVByb21wdC5zZXRTZWxlY3Rpb24oc2F2ZUVkaXRvcnMgPT0gU2VydmVyVUlQcmVmZXJlbmNlcy5TQVZFX0VESVRPUlNfUFJPTVBUKTsKCQlzYXZlQXV0by5zZXRTZWxlY3Rpb24oc2F2ZUVkaXRvcnMgPT0gU2VydmVyVUlQcmVmZXJlbmNlcy5TQVZFX0VESVRPUlNfQVVUTyk7IAoJfQoJCgkvKioKCSAqIEluaXRpYWxpemVzIHRoaXMgcHJlZmVyZW5jZSBwYWdlIHVzaW5nIHRoZSBwYXNzZWQgd29ya2JlbmNoLgoJICoKCSAqIEBwYXJhbSB3b3JrYmVuY2ggdGhlIGN1cnJlbnQgd29ya2JlbmNoCgkgKi8KCXB1YmxpYyB2b2lkIGluaXQoSVdvcmtiZW5jaCB3b3JrYmVuY2gpIHsKCQkvLyBkbyBub3RoaW5nCgl9CgkKCS8qKgoJICogUGVyZm9ybXMgc3BlY2lhbCBwcm9jZXNzaW5nIHdoZW4gdGhpcyBwYWdlJ3MgRGVmYXVsdHMgYnV0dG9uIGhhcyBiZWVuIHByZXNzZWQuCgkgKi8KCXByb3RlY3RlZCB2b2lkIHBlcmZvcm1EZWZhdWx0cygpIHsKCQlhdXRvUmVzdGFydC5zZXRTZWxlY3Rpb24ocHJlZmVyZW5jZXMuaXNEZWZhdWx0QXV0b1Jlc3RhcnRpbmcoKSk7CgkJcHVibGlzaEJlZm9yZVN0YXJ0LnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5pc0RlZmF1bHRBdXRvUHVibGlzaGluZygpKTsKCQlwcm9tcHRJcnJldmVyc2libGUuc2V0U2VsZWN0aW9uKHVpUHJlZmVyZW5jZXMuZ2V0RGVmYXVsdFByb21wdEJlZm9yZUlycmV2ZXJzaWJsZUNoYW5nZSgpKTsKCQlzaG93T25BY3Rpdml0eS5zZXRTZWxlY3Rpb24odWlQcmVmZXJlbmNlcy5nZXREZWZhdWx0U2hvd09uQWN0aXZpdHkoKSk7CgkJY3JlYXRlSW5Xb3Jrc3BhY2Uuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmlzRGVmYXVsdENyZWF0ZVJlc291cmNlc0luV29ya3NwYWNlKCkpOwoJCQoJCWF1dG9QdWJsaXNoTG9jYWwuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmdldERlZmF1bHRBdXRvUHVibGlzaExvY2FsKCkpOwoJCWF1dG9QdWJsaXNoTG9jYWxUaW1lLnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5nZXREZWZhdWx0QXV0b1B1Ymxpc2hMb2NhbFRpbWUoKSk7CgkJYXV0b1B1Ymxpc2hSZW1vdGUuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmdldERlZmF1bHRBdXRvUHVibGlzaFJlbW90ZSgpKTsKCQlhdXRvUHVibGlzaFJlbW90ZVRpbWUuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmdldERlZmF1bHRBdXRvUHVibGlzaFJlbW90ZVRpbWUoKSk7CgkJCgkJc2V0U2F2ZUVkaXRvclN0YXR1cyh1aVByZWZlcmVuY2VzLmdldERlZmF1bHRTYXZlRWRpdG9ycygpKTsKCQoJCXN1cGVyLnBlcmZvcm1EZWZhdWx0cygpOwoJfQoKCS8qKgoJICogTWV0aG9kIGRlY2xhcmVkIG9uIElQcmVmZXJlbmNlUGFnZS4KCSAqIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlCgkgKi8KCXB1YmxpYyBib29sZWFuIHBlcmZvcm1PaygpIHsKCQlwcmVmZXJlbmNlcy5zZXRBdXRvUHVibGlzaGluZyhwdWJsaXNoQmVmb3JlU3RhcnQuZ2V0U2VsZWN0aW9uKCkpOwoJCXByZWZlcmVuY2VzLnNldEF1dG9SZXN0YXJ0aW5nKGF1dG9SZXN0YXJ0LmdldFNlbGVjdGlvbigpKTsKCQl1aVByZWZlcmVuY2VzLnNldFNhdmVFZGl0b3JzKHNhdmVFZGl0b3JzKTsKCQl1aVByZWZlcmVuY2VzLnNldFByb21wdEJlZm9yZUlycmV2ZXJzaWJsZUNoYW5nZShwcm9tcHRJcnJldmVyc2libGUuZ2V0U2VsZWN0aW9uKCkpOwoJCXVpUHJlZmVyZW5jZXMuc2V0U2hvd09uQWN0aXZpdHkoc2hvd09uQWN0aXZpdHkuZ2V0U2VsZWN0aW9uKCkpOwoJCXByZWZlcmVuY2VzLnNldENyZWF0ZVJlc291cmNlc0luV29ya3NwYWNlKGNyZWF0ZUluV29ya3NwYWNlLmdldFNlbGVjdGlvbigpKTsKCQkKCQlwcmVmZXJlbmNlcy5zZXRBdXRvUHVibGlzaExvY2FsKGF1dG9QdWJsaXNoTG9jYWwuZ2V0U2VsZWN0aW9uKCkpOwoJCXByZWZlcmVuY2VzLnNldEF1dG9QdWJsaXNoTG9jYWxUaW1lKGF1dG9QdWJsaXNoTG9jYWxUaW1lLmdldFNlbGVjdGlvbigpKTsKCQlwcmVmZXJlbmNlcy5zZXRBdXRvUHVibGlzaFJlbW90ZShhdXRvUHVibGlzaFJlbW90ZS5nZXRTZWxlY3Rpb24oKSk7CgkJcHJlZmVyZW5jZXMuc2V0QXV0b1B1Ymxpc2hSZW1vdGVUaW1lKGF1dG9QdWJsaXNoUmVtb3RlVGltZS5nZXRTZWxlY3Rpb24oKSk7CgkKCQkvLyBhdXRvIHJlc3RhcnQgYW55IHNlcnZlcnMgdGhhdCBhcmUgcmVhZHkgZm9yIHJlc3RhcnQKCQlpZiAoYXV0b1Jlc3RhcnQuZ2V0U2VsZWN0aW9uKCkpCgkJCWF1dG9SZXN0YXJ0QWxsKCk7CgkKCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIEF1dG9tYXRpY2FsbHkgcmVzdGFydCBhbnkgc2VydmVycyB0aGF0IHJlcXVpcmUgaXQuCgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgdm9pZCBhdXRvUmVzdGFydEFsbCgpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJBdXRvIHJlc3RhcnRpbmcgYWxsIGRpcnR5IHNlcnZlcnMiKTsKCQoJCUlTZXJ2ZXJbXSBzZXJ2ZXJzID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJzKCk7CgkJaWYgKHNlcnZlcnMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlcnMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSVNlcnZlciBzZXJ2ZXIgPSBzZXJ2ZXJzW2ldOwoJCQkJaWYgKHNlcnZlci5nZXRTZXJ2ZXJSZXN0YXJ0U3RhdGUoKSkgewoJCQkJCVN0cmluZyBtb2RlID0gc2VydmVyLmdldE1vZGUoKTsKCQkJCQlpZiAoc2VydmVyLmNhblJlc3RhcnQobW9kZSkuaXNPSygpKQoJCQkJCQl0cnkgewoJCQkJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiQXR0ZW1wdGluZyB0byBhdXRvIHJlc3RhcnQgIiArIHNlcnZlci5nZXROYW1lKCkpOwoJCQkJCQkJc2VydmVyLnJlc3RhcnQobW9kZSk7CgkJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciByZXN0YXJ0aW5nOiAiICsgc2VydmVyLCBlKTsKCQkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJfQp9