LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwud2l6YXJkLnBhZ2U7CgppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbjsKCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLkRpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuSU1lc3NhZ2VQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLm9wZXJhdGlvbi5JUnVubmFibGVXaXRoUHJvZ3Jlc3M7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5yZXNvdXJjZS5KRmFjZVJlc291cmNlczsKCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmN1c3RvbS5TdGFja0xheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29udHJvbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGV4dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmhlbHAuV29ya2JlbmNoSGVscDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklNb2R1bGVUeXBlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklSdW50aW1lOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlckF0dHJpYnV0ZXM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlclR5cGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlcldvcmtpbmdDb3B5OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklUYXNrTW9kZWw7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyQ29yZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5TZXJ2ZXJVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC52aWV3ZXJzLlNlcnZlckNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwud2l6YXJkLmZyYWdtZW50Lk5ld1NlcnZlcldpemFyZEZyYWdtZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS53aXphcmQuSVdpemFyZEhhbmRsZTsKLyoqCiAqIEEgd2l6YXJkIHBhZ2UgdXNlZCB0byBzZWxlY3QgYSBzZXJ2ZXIgY2xpZW50LgogKi8KcHVibGljIGNsYXNzIE5ld1NlcnZlckNvbXBvc2l0ZSBleHRlbmRzIENvbXBvc2l0ZSB7Cglwcm90ZWN0ZWQgSVdpemFyZEhhbmRsZSB3aXphcmQ7Cglwcm90ZWN0ZWQgSVRhc2tNb2RlbCB0YXNrTW9kZWw7Cglwcm90ZWN0ZWQgSU1vZHVsZSBtb2R1bGU7Cglwcm90ZWN0ZWQgU3RyaW5nIGxhdW5jaE1vZGU7CgkKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBNT0RFX0VYSVNUSU5HID0gMDsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgYnl0ZSBNT0RFX0RFVEVDVCA9IDE7Cglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJ5dGUgTU9ERV9NQU5VQUw9IDI7Cglwcm90ZWN0ZWQgYnl0ZSBtb2RlOwoKCXByb3RlY3RlZCBDb21wb3NpdGUgZGV0ZWN0Q29tcDI7Cglwcm90ZWN0ZWQgTmV3RGV0ZWN0U2VydmVyQ29tcG9zaXRlIGRldGVjdENvbXA7Cglwcm90ZWN0ZWQgSG9zdG5hbWVDb21wb3NpdGUgZGV0ZWN0SG9zdENvbXA7Cglwcm90ZWN0ZWQgQ29tcG9zaXRlIG1hbnVhbENvbXAyOwoJcHJvdGVjdGVkIE5ld01hbnVhbFNlcnZlckNvbXBvc2l0ZSBtYW51YWxDb21wOwoJcHJvdGVjdGVkIEhvc3RuYW1lQ29tcG9zaXRlIG1hbnVhbEhvc3RDb21wOwoJcHJvdGVjdGVkIFNlcnZlckNvbXBvc2l0ZSBleGlzdGluZ0NvbXA7CgkKCXByb3RlY3RlZCBDb21wb3NpdGUgc3RhY2s7Cglwcm90ZWN0ZWQgU3RhY2tMYXlvdXQgc3RhY2tMYXlvdXQ7IAoJCglwcm90ZWN0ZWQgU3RyaW5nIGxhc3RIb3N0bmFtZTsKCQoJcHJvdGVjdGVkIEJ1dHRvbiBwcmVmOwoJcHJvdGVjdGVkIGJvb2xlYW4gcHJlZmVycmVkOwoJCglwcm90ZWN0ZWQgSVNlcnZlcldvcmtpbmdDb3B5IGV4aXN0aW5nV0M7CgoJLyoqCgkgKiBDcmVhdGUgYSBuZXcgTmV3U2VydmVyQ29tcG9zaXRlLgoJICovCglwdWJsaWMgTmV3U2VydmVyQ29tcG9zaXRlKENvbXBvc2l0ZSBwYXJlbnQsIElXaXphcmRIYW5kbGUgd2l6YXJkLCBJTW9kdWxlIG1vZHVsZSwgU3RyaW5nIGxhdW5jaE1vZGUpIHsKCQlzdXBlcihwYXJlbnQsIFNXVC5OT05FKTsKCQl0aGlzLndpemFyZCA9IHdpemFyZDsKCQl0aGlzLm1vZHVsZSA9IG1vZHVsZTsKCQl0aGlzLmxhdW5jaE1vZGUgPSBsYXVuY2hNb2RlOwoJCgkJd2l6YXJkLnNldFRpdGxlKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6TmV3U2VydmVyVGl0bGUiKSk7CgkJd2l6YXJkLnNldERlc2NyaXB0aW9uKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6TmV3U2VydmVyRGVzY3JpcHRpb24iKSk7CgkJd2l6YXJkLnNldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19XSVpCQU5fTkVXX1NFUlZFUikpOwoJCQoJCWNyZWF0ZUNvbnRyb2woKTsKCX0KCglwdWJsaWMgTmV3U2VydmVyQ29tcG9zaXRlKENvbXBvc2l0ZSBwYXJlbnQsIElXaXphcmRIYW5kbGUgd2l6YXJkKSB7CgkJdGhpcyhwYXJlbnQsIHdpemFyZCwgbnVsbCwgbnVsbCk7Cgl9CgkKCXByb3RlY3RlZCBMYWJlbCBjcmVhdGVIZWFkaW5nTGFiZWwoQ29tcG9zaXRlIHBhcmVudCwgU3RyaW5nIHRleHQsIGludCBzcGFuKSB7CgkJTGFiZWwgbGFiZWwgPSBjcmVhdGVMYWJlbChwYXJlbnQsIHRleHQsIHNwYW4pOwoJCWxhYmVsLnNldEZvbnQoSkZhY2VSZXNvdXJjZXMuZ2V0QmFubmVyRm9udCgpKTsKCQlyZXR1cm4gbGFiZWw7Cgl9CgkKCXByb3RlY3RlZCBMYWJlbCBjcmVhdGVMYWJlbChDb21wb3NpdGUgcGFyZW50LCBTdHJpbmcgdGV4dCwgaW50IHNwYW4pIHsKCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChwYXJlbnQsIFNXVC5XUkFQKTsKCQlsYWJlbC5zZXRUZXh0KHRleHQpOwoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMIHwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fQkVHSU5OSU5HKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gc3BhbjsKCQlsYWJlbC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCXJldHVybiBsYWJlbDsKCX0KCQoJcHJvdGVjdGVkIExhYmVsIGNyZWF0ZUxhYmVsKENvbXBvc2l0ZSBwYXJlbnQsIFN0cmluZyB0ZXh0KSB7CgkJcmV0dXJuIGNyZWF0ZUxhYmVsKHBhcmVudCwgdGV4dCwgMSk7Cgl9CgkKCXByb3RlY3RlZCBCdXR0b24gY3JlYXRlUmFkaW9CdXR0b24oQ29tcG9zaXRlIHBhcmVudCwgU3RyaW5nIHRleHQsIGludCBzcGFuKSB7CgkJQnV0dG9uIGJ1dHRvbiA9IG5ldyBCdXR0b24ocGFyZW50LCBTV1QuUkFESU8pOwoJCWJ1dHRvbi5zZXRUZXh0KHRleHQpOwoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMIHwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fQkVHSU5OSU5HKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gc3BhbjsKCQlkYXRhLmhvcml6b250YWxJbmRlbnQgPSAxMDsKCQlidXR0b24uc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlyZXR1cm4gYnV0dG9uOwoJfQoJCglwcm90ZWN0ZWQgVGV4dCBjcmVhdGVUZXh0KENvbXBvc2l0ZSBwYXJlbnQsIFN0cmluZyB0ZXh0MiwgaW50IHNwYW4pIHsKCQlUZXh0IHRleHQgPSBuZXcgVGV4dChwYXJlbnQsIFNXVC5OT05FKTsKCQl0ZXh0LnNldFRleHQodGV4dDIpOwoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMIHwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fQkVHSU5OSU5HKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gc3BhbjsKCQl0ZXh0LnNldExheW91dERhdGEoZGF0YSk7CgkJcmV0dXJuIHRleHQ7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIHRoZSBVSSBvZiB0aGUgcGFnZS4KCSAqCgkgKiBAcGFyYW0gb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlIHBhcmVudAoJICovCglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVDb250cm9sKCkgewoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSBTV1RVdGlsLmNvbnZlcnRIb3Jpem9udGFsRExVc1RvUGl4ZWxzKHRoaXMsIDQpOwoJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSBTV1RVdGlsLmNvbnZlcnRWZXJ0aWNhbERMVXNUb1BpeGVscyh0aGlzLCA0KTsKCQlsYXlvdXQubWFyZ2luV2lkdGggPSAwOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSAwOwoJCWxheW91dC5udW1Db2x1bW5zID0gMTsKCQlzZXRMYXlvdXQobGF5b3V0KTsKCQkvL1dvcmtiZW5jaEhlbHAuc2V0SGVscCh0aGlzLCBDb250ZXh0SWRzLlNFTEVDVF9DTElFTlRfV0laQVJEKTsKCQoJCWlmIChtb2R1bGUgIT0gbnVsbCkKCQkJY3JlYXRlSGVhZGluZ0xhYmVsKHRoaXMsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6TmV3U2VydmVyU2VsZWN0IiksIDEpOwoJCQkKCQlCdXR0b24gZXhpc3RpbmcgPSBudWxsOwoJCWlmIChtb2R1bGUgIT0gbnVsbCkgewoJCQlmaW5hbCBCdXR0b24gcHJlZGVmaW5lZCA9IGNyZWF0ZVJhZGlvQnV0dG9uKHRoaXMsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6TmV3U2VydmVyRXhpc3RpbmciKSwgMSk7CgkJCXByZWRlZmluZWQuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQkJaWYgKHByZWRlZmluZWQuZ2V0U2VsZWN0aW9uKCkpCgkJCQkJCXRvZ2dsZU1vZGUoTU9ERV9FWElTVElORyk7CgkJCQl9CgkJCX0pOwoJCQlleGlzdGluZyA9IHByZWRlZmluZWQ7CgkJfQoJCQoJCS8qZmluYWwgQnV0dG9uIGF1dG8gPSBjcmVhdGVSYWRpb0J1dHRvbih0aGlzLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpek5ld1NlcnZlckRldGVjdCIpLCAxKTsKCQlhdXRvLnNldEVuYWJsZWQoZmFsc2UpOwoJCWF1dG8uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCWlmIChhdXRvLmdldFNlbGVjdGlvbigpKQoJCQkJCXRvZ2dsZU1vZGUoTU9ERV9ERVRFQ1QpOwoJCQl9CgkJfSk7Ki8KCQoJCUJ1dHRvbiBtYW51YWwgPSBudWxsOwoJCWlmIChtb2R1bGUgIT0gbnVsbCkgewoJCQlmaW5hbCBCdXR0b24gbWFudWFsQnV0dG9uID0gY3JlYXRlUmFkaW9CdXR0b24odGhpcywgU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpOZXdTZXJ2ZXJNYW51YWwiKSwgMSk7CgkJCW1hbnVhbEJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCQlpZiAobWFudWFsQnV0dG9uLmdldFNlbGVjdGlvbigpKQoJCQkJCQl0b2dnbGVNb2RlKE1PREVfTUFOVUFMKTsKCQkJCX0KCQkJfSk7CgkJCW1hbnVhbCA9IG1hbnVhbEJ1dHRvbjsKCQl9CgkJCgkJc3RhY2sgPSBuZXcgQ29tcG9zaXRlKHRoaXMsIFNXVC5OT05FKTsKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0JFR0lOTklORyk7CgkJc3RhY2suc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlzdGFja0xheW91dCA9IG5ldyBTdGFja0xheW91dCgpOwoJCXN0YWNrTGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7CgkJc3RhY2tMYXlvdXQubWFyZ2luV2lkdGggPSAwOwoJCXN0YWNrLnNldExheW91dChzdGFja0xheW91dCk7CgkJCgkJaWYgKG1vZHVsZSAhPSBudWxsKQoJCQljcmVhdGVFeGlzdGluZ0NvbXBvc2l0ZShzdGFjayk7CgkJY3JlYXRlQXV0b0NvbXBvc2l0ZShzdGFjayk7CgkJY3JlYXRlTWFudWFsQ29tcG9zaXRlKHN0YWNrKTsKCQoJCWlmIChleGlzdGluZ0NvbXAgIT0gbnVsbCkgewoJCQlpZiAoaXNFeGlzdGluZ1NlcnZlcigpKSB7CgkJCQltb2RlID0gTU9ERV9FWElTVElORzsKCQkJCXN0YWNrTGF5b3V0LnRvcENvbnRyb2wgPSBleGlzdGluZ0NvbXA7CgkJCQlleGlzdGluZy5zZXRTZWxlY3Rpb24odHJ1ZSk7CgkJCX0gZWxzZSB7CgkJCQltb2RlID0gTU9ERV9NQU5VQUw7CgkJCQlzdGFja0xheW91dC50b3BDb250cm9sID0gbWFudWFsQ29tcDI7CgkJCQltYW51YWxDb21wLnNldFZpc2libGUodHJ1ZSk7CgkJCQlpZiAobWFudWFsICE9IG51bGwpCgkJCQkJbWFudWFsLnNldFNlbGVjdGlvbih0cnVlKTsKCQkJCWV4aXN0aW5nLnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJZXhpc3RpbmdDb21wLnNldEVuYWJsZWQoZmFsc2UpOwoJCQl9CgkJfSBlbHNlIHsKCQkJbW9kZSA9IE1PREVfTUFOVUFMOwoJCQlzdGFja0xheW91dC50b3BDb250cm9sID0gbWFudWFsQ29tcDI7CgkJCW1hbnVhbENvbXAuc2V0VmlzaWJsZSh0cnVlKTsKCQkJaWYgKG1hbnVhbCAhPSBudWxsKQoJCQkJbWFudWFsLnNldFNlbGVjdGlvbih0cnVlKTsKCQl9CgkJCgkJaWYgKG1vZHVsZSAhPSBudWxsKSB7CgkJCS8vIHByZWZlcnJlZCBzZXJ2ZXIgYnV0dG9uCgkJCXByZWYgPSBuZXcgQnV0dG9uKHRoaXMsIFNXVC5DSEVDSyB8IFNXVC5XUkFQKTsKCQkJcHJlZi5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6U2VsZWN0U2VydmVyUHJlZmVycmVkIikpOwoJCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0VORCk7CgkJCS8vcHJlZi5zZXRTZWxlY3Rpb24odHJ1ZSk7CgkJCS8vcHJlZmVycmVkID0gdHJ1ZTsKCQkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDE7CgkJCXByZWYuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJcHJlZi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCQlwcmVmZXJyZWQgPSBwcmVmLmdldFNlbGVjdGlvbigpOwoJCQkJfQoJCQl9KTsKCQkJV29ya2JlbmNoSGVscC5zZXRIZWxwKHByZWYsIENvbnRleHRJZHMuU0VMRUNUX1NFUlZFUl9QUkVGRVJFTkNFKTsKCQl9CgkJCgkJRGlhbG9nLmFwcGx5RGlhbG9nRm9udCh0aGlzKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgdG9nZ2xlTW9kZShieXRlIG5ld01vZGUpIHsKCQlpZiAoIWlzVmlzaWJsZSgpKQoJCQlyZXR1cm47CgoJCWlmIChuZXdNb2RlID09IG1vZGUpCgkJCXJldHVybjsKCQkKCQltb2RlID0gbmV3TW9kZTsKCQl3aXphcmQuc2V0TWVzc2FnZShudWxsLCBJTWVzc2FnZVByb3ZpZGVyLk5PTkUpOwoJCQoJCWlmIChtb2RlID09IE1PREVfRVhJU1RJTkcpIHsKCQkJc3RhY2tMYXlvdXQudG9wQ29udHJvbCA9IGV4aXN0aW5nQ29tcDsKCQkJZXhpc3RpbmdDb21wLnNldFNlbGVjdGlvbihleGlzdGluZ0NvbXAuZ2V0U2VsZWN0ZWRTZXJ2ZXIoKSk7CgkJfSBlbHNlIGlmIChtb2RlID09IE1PREVfREVURUNUKSB7CgkJCXN0YWNrTGF5b3V0LnRvcENvbnRyb2wgPSBkZXRlY3RDb21wMjsKCQkJZGV0ZWN0Q29tcC5zZXRWaXNpYmxlKHRydWUpOwoJCX0gZWxzZSB7CgkJCXN0YWNrTGF5b3V0LnRvcENvbnRyb2wgPSBtYW51YWxDb21wMjsKCQkJbWFudWFsQ29tcC5zZXRWaXNpYmxlKHRydWUpOwoJCX0KCQlzdGFjay5sYXlvdXQoKTsKCQlpZiAodGFza01vZGVsICE9IG51bGwpIHsKCQkJdGFza01vZGVsLnB1dE9iamVjdChOZXdTZXJ2ZXJXaXphcmRGcmFnbWVudC5NT0RFLCBuZXcgQnl0ZShtb2RlKSk7CgkJCXVwZGF0ZVRhc2tNb2RlbCgpOwoJCX0KCX0KCQoJcHJvdGVjdGVkIEhvc3RuYW1lQ29tcG9zaXRlIGNyZWF0ZUhvc3RDb21wb3NpdGUoQ29tcG9zaXRlIGNvbXApIHsKCQlIb3N0bmFtZUNvbXBvc2l0ZSBob3N0Q29tcCA9IG5ldyBIb3N0bmFtZUNvbXBvc2l0ZShjb21wLCBuZXcgSG9zdG5hbWVDb21wb3NpdGUuSUhvc3RuYW1lU2VsZWN0aW9uTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIGhvc3RuYW1lU2VsZWN0ZWQoU3RyaW5nIGhvc3QpIHsKCQkJCWxhc3RIb3N0bmFtZSA9IGhvc3Q7CgkJCQlpZiAoZGV0ZWN0Q29tcCAhPSBudWxsKQoJCQkJCWRldGVjdENvbXAuc2V0SG9zdChob3N0KTsKCQkJCWlmIChtYW51YWxDb21wICE9IG51bGwpCgkJCQkJbWFudWFsQ29tcC5zZXRIb3N0KGhvc3QpOwoJCQl9CgkJfSk7CgkJCgkJaWYgKGxhc3RIb3N0bmFtZSAhPSBudWxsKQoJCQlob3N0Q29tcC5zZXRIb3N0bmFtZShsYXN0SG9zdG5hbWUpOwoJCQoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQlob3N0Q29tcC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCXJldHVybiBob3N0Q29tcDsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlQXV0b0NvbXBvc2l0ZShDb21wb3NpdGUgY29tcCkgewoJCWRldGVjdENvbXAyID0gbmV3IENvbXBvc2l0ZShjb21wLCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5ob3Jpem9udGFsU3BhY2luZyA9IFNXVFV0aWwuY29udmVydEhvcml6b250YWxETFVzVG9QaXhlbHModGhpcywgNCk7CgkJbGF5b3V0LnZlcnRpY2FsU3BhY2luZyA9IFNXVFV0aWwuY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKHRoaXMsIDQpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7CgkJbGF5b3V0Lm51bUNvbHVtbnMgPSAxOwoJCWRldGVjdENvbXAyLnNldExheW91dChsYXlvdXQpOwoJCQoJCWRldGVjdEhvc3RDb21wID0gY3JlYXRlSG9zdENvbXBvc2l0ZShkZXRlY3RDb21wMik7CgkJCgkJZGV0ZWN0Q29tcCA9IG5ldyBOZXdEZXRlY3RTZXJ2ZXJDb21wb3NpdGUoZGV0ZWN0Q29tcDIsIG5ldyBOZXdEZXRlY3RTZXJ2ZXJDb21wb3NpdGUuSVNlcnZlclNlbGVjdGlvbkxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBzZXJ2ZXJTZWxlY3RlZChJU2VydmVyQXR0cmlidXRlcyBzZXJ2ZXIpIHsKCQkJCS8vIGRvIG5vdGhpbmcKCQkJfQoJCX0pOwoKCQlpZiAobGFzdEhvc3RuYW1lICE9IG51bGwpCgkJCWRldGVjdENvbXAuc2V0SG9zdChsYXN0SG9zdG5hbWUpOwoJCWVsc2UKCQkJZGV0ZWN0Q29tcC5zZXRIb3N0KCJsb2NhbGhvc3QiKTsKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0ZJTEwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCWRhdGEuaGVpZ2h0SGludCA9IDEyMDsKCQlkZXRlY3RDb21wLnNldExheW91dERhdGEoZGF0YSk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlRXhpc3RpbmdDb21wb3NpdGUoQ29tcG9zaXRlIGNvbXApIHsKCQlleGlzdGluZ0NvbXAgPSBuZXcgU2VydmVyQ29tcG9zaXRlKGNvbXAsIFNXVC5OT05FLCBuZXcgU2VydmVyQ29tcG9zaXRlLlNlcnZlclNlbGVjdGlvbkxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBzZXJ2ZXJTZWxlY3RlZChJU2VydmVyIHNlcnZlcikgewoJCQkJd2l6YXJkLnNldE1lc3NhZ2UobnVsbCwgSU1lc3NhZ2VQcm92aWRlci5OT05FKTsKCQkJCQoJCQkJLy8gY2hlY2sgZm9yIGNvbXBhdGliaWxpdHkKCQkJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiBtb2R1bGUgIT0gbnVsbCkgewoJCQkJCUlTZXJ2ZXJUeXBlIHNlcnZlclR5cGUgPSBzZXJ2ZXIuZ2V0U2VydmVyVHlwZSgpOwoJCQkJCUlNb2R1bGVUeXBlIG10ID0gbW9kdWxlLmdldE1vZHVsZVR5cGUoKTsKCQkJCQlpZiAoIVNlcnZlclV0aWwuaXNTdXBwb3J0ZWRNb2R1bGUoc2VydmVyVHlwZS5nZXRSdW50aW1lVHlwZSgpLmdldE1vZHVsZVR5cGVzKCksIG10KSkgewoJCQkJCQlTdHJpbmcgdHlwZSA9IG10LmdldE5hbWUoKTsKCQkJCQkJd2l6YXJkLnNldE1lc3NhZ2UoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlcnJvclZlcnNpb25MZXZlbCIsIG5ldyBPYmplY3RbXSB7IHR5cGUsIG10LmdldFZlcnNpb24oKSB9KSwgSU1lc3NhZ2VQcm92aWRlci5FUlJPUik7CgkJCQkJCXNlcnZlciA9IG51bGw7CgkJCQkJfQoJCQkJfQoJCQkJCgkJCQlpZiAoZXhpc3RpbmdXQyAhPSBudWxsKSB7CgkJCQkJaWYgKHNlcnZlciAhPSBudWxsICYmIHNlcnZlci5lcXVhbHMoZXhpc3RpbmdXQy5nZXRPcmlnaW5hbCgpKSkKCQkJCQkJcmV0dXJuOwoJCQkJCWV4aXN0aW5nV0MgPSBudWxsOwoJCQkJfQoJCQkJaWYgKHNlcnZlciAhPSBudWxsKQoJCQkJCWV4aXN0aW5nV0MgPSBzZXJ2ZXIuY3JlYXRlV29ya2luZ0NvcHkoKTsKCQkJCXVwZGF0ZVRhc2tNb2RlbCgpOwoJCQl9CgkJfSwgbW9kdWxlLCBsYXVuY2hNb2RlKTsKCQlleGlzdGluZ0NvbXAuc2V0SW5jbHVkZUluY29tcGF0aWJsZVZlcnNpb25zKHRydWUpOwoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMIHwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fRklMTCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJZGF0YS5oZWlnaHRIaW50ID0gMTIwOwoJCWV4aXN0aW5nQ29tcC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJfQoJCglwcm90ZWN0ZWQgYm9vbGVhbiBpc0V4aXN0aW5nU2VydmVyKCkgewoJCWlmIChtb2R1bGUgPT0gbnVsbCB8fCBsYXVuY2hNb2RlID09IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCQkKCQlJU2VydmVyW10gc2VydmVycyA9IFNlcnZlckNvcmUuZ2V0U2VydmVycygpOwoJCWlmIChzZXJ2ZXJzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXJzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlNb2R1bGVUeXBlIG10ID0gbW9kdWxlLmdldE1vZHVsZVR5cGUoKTsKCQkJCWlmIChTZXJ2ZXJVdGlsLmlzQ29tcGF0aWJsZVdpdGhMYXVuY2hNb2RlKHNlcnZlcnNbaV0sIGxhdW5jaE1vZGUpICYmCgkJCQkJU2VydmVyVXRpbC5pc1N1cHBvcnRlZE1vZHVsZShzZXJ2ZXJzW2ldLmdldFNlcnZlclR5cGUoKS5nZXRSdW50aW1lVHlwZSgpLmdldE1vZHVsZVR5cGVzKCksIG10KSkKCQkJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXByb3RlY3RlZCB2b2lkIGNyZWF0ZU1hbnVhbENvbXBvc2l0ZShDb21wb3NpdGUgY29tcCkgewoJCW1hbnVhbENvbXAyID0gbmV3IENvbXBvc2l0ZShjb21wLCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5ob3Jpem9udGFsU3BhY2luZyA9IFNXVFV0aWwuY29udmVydEhvcml6b250YWxETFVzVG9QaXhlbHModGhpcywgNCk7CgkJbGF5b3V0LnZlcnRpY2FsU3BhY2luZyA9IFNXVFV0aWwuY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKHRoaXMsIDQpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7CgkJbGF5b3V0Lm51bUNvbHVtbnMgPSAxOwoJCW1hbnVhbENvbXAyLnNldExheW91dChsYXlvdXQpOwoJCQoJCW1hbnVhbEhvc3RDb21wID0gY3JlYXRlSG9zdENvbXBvc2l0ZShtYW51YWxDb21wMik7CgkJSU1vZHVsZVR5cGUgbXQgPSBudWxsOwoJCWlmIChtb2R1bGUgIT0gbnVsbCkKCQkJbXQgPSBtb2R1bGUuZ2V0TW9kdWxlVHlwZSgpOwoJCQoJCW1hbnVhbENvbXAgPSBuZXcgTmV3TWFudWFsU2VydmVyQ29tcG9zaXRlKG1hbnVhbENvbXAyLCBuZXcgTmV3TWFudWFsU2VydmVyQ29tcG9zaXRlLklXaXphcmRIYW5kbGUyKCkgewoJCQlwdWJsaWMgdm9pZCBydW4oYm9vbGVhbiBmb3JrLCBib29sZWFuIGNhbmNlbGFibGUsIElSdW5uYWJsZVdpdGhQcm9ncmVzcyBydW5uYWJsZSkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIHsKCQkJCXdpemFyZC5ydW4oZm9yaywgY2FuY2VsYWJsZSwgcnVubmFibGUpOwoJCQl9CgkJCXB1YmxpYyB2b2lkIHVwZGF0ZSgpIHsKCQkJCXdpemFyZC51cGRhdGUoKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBzZXRNZXNzYWdlKFN0cmluZyBuZXdNZXNzYWdlLCBpbnQgbmV3VHlwZSkgewoJCQkJd2l6YXJkLnNldE1lc3NhZ2UobmV3TWVzc2FnZSwgbmV3VHlwZSk7CgkJCX0KCQl9LCBtdCwgbmV3IE5ld01hbnVhbFNlcnZlckNvbXBvc2l0ZS5TZXJ2ZXJTZWxlY3Rpb25MaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgc2VydmVyU2VsZWN0ZWQoSVNlcnZlckF0dHJpYnV0ZXMgc2VydmVyKSB7CgkJCQl1cGRhdGVUYXNrTW9kZWwoKTsKCQkJfQoJCX0pOwoJCQoJCWlmIChsYXN0SG9zdG5hbWUgIT0gbnVsbCkKCQkJbWFudWFsQ29tcC5zZXRIb3N0KGxhc3RIb3N0bmFtZSk7CgkJZWxzZQoJCQltYW51YWxDb21wLnNldEhvc3QoImxvY2FsaG9zdCIpOwoKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0ZJTEwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCWRhdGEuaGVpZ2h0SGludCA9IDIwMDsKCQltYW51YWxDb21wLnNldExheW91dERhdGEoZGF0YSk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgdXBkYXRlVGFza01vZGVsKCkgewoJCWlmICh0YXNrTW9kZWwgIT0gbnVsbCkgewoJCQlJU2VydmVyV29ya2luZ0NvcHkgc2VydmVyID0gZ2V0U2VydmVyKCk7CgkJCWlmIChzZXJ2ZXIgIT0gbnVsbCkgewoJCQkJdGFza01vZGVsLnB1dE9iamVjdChJVGFza01vZGVsLlRBU0tfU0VSVkVSLCBzZXJ2ZXIpOwoJCQkJdGFza01vZGVsLnB1dE9iamVjdChJVGFza01vZGVsLlRBU0tfUlVOVElNRSwgc2VydmVyLmdldFJ1bnRpbWUoKSk7CgkJCX0gZWxzZSB7CgkJCQl0YXNrTW9kZWwucHV0T2JqZWN0KElUYXNrTW9kZWwuVEFTS19TRVJWRVIsIG51bGwpOwoJCQkJdGFza01vZGVsLnB1dE9iamVjdChJVGFza01vZGVsLlRBU0tfUlVOVElNRSwgbnVsbCk7CgkJCX0KCQkJd2l6YXJkLnVwZGF0ZSgpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCBzZXRUYXNrTW9kZWwoSVRhc2tNb2RlbCBtb2RlbCkgewoJCXRhc2tNb2RlbCA9IG1vZGVsOwoJCXRhc2tNb2RlbC5wdXRPYmplY3QoTmV3U2VydmVyV2l6YXJkRnJhZ21lbnQuTU9ERSwgbmV3IEJ5dGUobW9kZSkpOwoJCXVwZGF0ZVRhc2tNb2RlbCgpOwoJfQoKCXB1YmxpYyBJU2VydmVyV29ya2luZ0NvcHkgZ2V0U2VydmVyKCkgewoJCWlmIChtb2RlID09IE1PREVfRVhJU1RJTkcpCgkJCXJldHVybiBleGlzdGluZ1dDOyAvL2V4aXN0aW5nQ29tcC5nZXRTZWxlY3RlZFNlcnZlcigpOwoJCWVsc2UgaWYgKG1vZGUgPT0gTU9ERV9ERVRFQ1QpCgkJCXJldHVybiBkZXRlY3RDb21wLmdldFNlcnZlcigpOwoJCWVsc2UKCQkJcmV0dXJuIG1hbnVhbENvbXAuZ2V0U2VydmVyKCk7Cgl9CgoJcHVibGljIElSdW50aW1lIGdldFJ1bnRpbWUoKSB7CgkJaWYgKG1vZGUgPT0gTU9ERV9FWElTVElORykgewoJCQlJU2VydmVyIHNlcnZlciA9IGV4aXN0aW5nQ29tcC5nZXRTZWxlY3RlZFNlcnZlcigpOwoJCQlpZiAoc2VydmVyICE9IG51bGwpCgkJCQlyZXR1cm4gc2VydmVyLmdldFJ1bnRpbWUoKTsKCQkJcmV0dXJuIG51bGw7CgkJfSBlbHNlIGlmIChtb2RlID09IE1PREVfREVURUNUKQoJCQlyZXR1cm4gbnVsbDsKCQllbHNlCgkJCXJldHVybiBtYW51YWxDb21wLmdldFJ1bnRpbWUoKTsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBzZXJ2ZXIgc2hvdWxkIGJlY29tZSB0aGUgcHJlZmVycmVkIHNlcnZlci4KCSAqIAoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzUHJlZmVycmVkU2VydmVyKCkgewoJCXJldHVybiBwcmVmZXJyZWQ7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFZpc2libGUoYm9vbGVhbiB2aXNpYmxlKSB7CgkJc3VwZXIuc2V0VmlzaWJsZSh2aXNpYmxlKTsKCQkKCQlDb250cm9sW10gYyA9IGdldENoaWxkcmVuKCk7CgkJaWYgKGMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykKCQkJCWlmIChjW2ldICE9IG51bGwpCgkJCQkJY1tpXS5zZXRWaXNpYmxlKHZpc2libGUpOwoJCX0KCX0KfQ==