LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWw7CgppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5EaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5wcmVmZXJlbmNlLlByZWZlcmVuY2VQYWdlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyQ29yZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXJQcmVmZXJlbmNlczsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkJ1dHRvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbWJvOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29udHJvbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkdyb3VwOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGFiZWw7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5TcGlubmVyOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklXb3JrYmVuY2hQcmVmZXJlbmNlUGFnZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLlBsYXRmb3JtVUk7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5oZWxwLklXb3JrYmVuY2hIZWxwU3lzdGVtOwovKioKICogVGhlIHByZWZlcmVuY2UgcGFnZSB0aGF0IGhvbGRzIHNlcnZlciBwcm9wZXJ0aWVzLgogKi8KcHVibGljIGNsYXNzIFNlcnZlclByZWZlcmVuY2VQYWdlIGV4dGVuZHMgUHJlZmVyZW5jZVBhZ2UgaW1wbGVtZW50cyBJV29ya2JlbmNoUHJlZmVyZW5jZVBhZ2UgewoJcHJvdGVjdGVkIEJ1dHRvbiBwdWJsaXNoQmVmb3JlU3RhcnQ7Cglwcm90ZWN0ZWQgQnV0dG9uIGF1dG9SZXN0YXJ0OwoKCXByb3RlY3RlZCBCdXR0b24gcHJvbXB0SXJyZXZlcnNpYmxlOwoJCglwcm90ZWN0ZWQgQnV0dG9uIHNob3dPbkFjdGl2aXR5OwoJCglwcm90ZWN0ZWQgYnl0ZSBzYXZlRWRpdG9yczsKCQoJcHJvdGVjdGVkIEJ1dHRvbiBzYXZlTmV2ZXI7Cglwcm90ZWN0ZWQgQnV0dG9uIHNhdmVQcm9tcHQ7Cglwcm90ZWN0ZWQgQnV0dG9uIHNhdmVBdXRvOwoJCglwcm90ZWN0ZWQgQnV0dG9uIGNyZWF0ZUluV29ya3NwYWNlOwoKCXByb3RlY3RlZCBTZXJ2ZXJQcmVmZXJlbmNlcyBwcmVmZXJlbmNlczsKCXByb3RlY3RlZCBTZXJ2ZXJVSVByZWZlcmVuY2VzIHVpUHJlZmVyZW5jZXM7CgkKCXByb3RlY3RlZCBCdXR0b24gYXV0b1B1Ymxpc2hPbkFjdGlvbjsKCXByb3RlY3RlZCBCdXR0b24gYXV0b1B1Ymxpc2hMb2NhbDsKCXByb3RlY3RlZCBTcGlubmVyIGF1dG9QdWJsaXNoTG9jYWxUaW1lOwoJcHJvdGVjdGVkIEJ1dHRvbiBhdXRvUHVibGlzaFJlbW90ZTsKCXByb3RlY3RlZCBTcGlubmVyIGF1dG9QdWJsaXNoUmVtb3RlVGltZTsKCQoJcHJvdGVjdGVkIENvbWJvIG1hY2hpbmVTcGVlZENvbWJvOwoKCS8qKgoJICogU2VydmVyUHJlZmVyZW5jZXNQYWdlIGNvbnN0cnVjdG9yIGNvbW1lbnQuCgkgKi8KCXB1YmxpYyBTZXJ2ZXJQcmVmZXJlbmNlUGFnZSgpIHsKCQlzdXBlcigpOwoJCgkJcHJlZmVyZW5jZXMgPSBTZXJ2ZXJQcmVmZXJlbmNlcy5nZXRJbnN0YW5jZSgpOwoJCXVpUHJlZmVyZW5jZXMgPSBTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpOwoJfQoJCgkvKioKCSAqIENyZWF0ZSB0aGUgcHJlZmVyZW5jZSBvcHRpb25zLgoJICoKCSAqIEBwYXJhbSBwYXJlbnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbnRyb2wKCSAqLwoJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlQ29udGVudHMoQ29tcG9zaXRlIHBhcmVudCkgewoJCWluaXRpYWxpemVEaWFsb2dVbml0cyhwYXJlbnQpOwoJCQoJCUNvbXBvc2l0ZSBjb21wb3NpdGUgPSBuZXcgQ29tcG9zaXRlKHBhcmVudCwgU1dULk5PTkUpOwoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSBjb252ZXJ0SG9yaXpvbnRhbERMVXNUb1BpeGVscyg0KTsKCQlsYXlvdXQudmVydGljYWxTcGFjaW5nID0gY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKDQpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7CgkJbGF5b3V0Lm51bUNvbHVtbnMgPSA0OwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXQobGF5b3V0KTsKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0ZJTEwpOwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCUlXb3JrYmVuY2hIZWxwU3lzdGVtIHdocyA9IFBsYXRmb3JtVUkuZ2V0V29ya2JlbmNoKCkuZ2V0SGVscFN5c3RlbSgpOwoJCXdocy5zZXRIZWxwKGNvbXBvc2l0ZSwgQ29udGV4dElkcy5QUkVGX0dFTkVSQUwpOwoJCQoJCXB1Ymxpc2hCZWZvcmVTdGFydCA9IG5ldyBCdXR0b24oY29tcG9zaXRlLCBTV1QuQ0hFQ0spOwoJCXB1Ymxpc2hCZWZvcmVTdGFydC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZkF1dG9QdWJsaXNoIikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gNDsKCQlwdWJsaXNoQmVmb3JlU3RhcnQuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlwdWJsaXNoQmVmb3JlU3RhcnQuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmlzQXV0b1B1Ymxpc2hpbmcoKSk7CgkJd2hzLnNldEhlbHAocHVibGlzaEJlZm9yZVN0YXJ0LCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTF9QVUJMSVNIX0JFRk9SRV9TVEFSVCk7CgkJCgkJYXV0b1B1Ymxpc2hMb2NhbCA9IG5ldyBCdXR0b24oY29tcG9zaXRlLCBTV1QuQ0hFQ0spOwoJCWF1dG9QdWJsaXNoTG9jYWwuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXByZWZBdXRvUHVibGlzaExvY2FsIikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gMjsKCQlhdXRvUHVibGlzaExvY2FsLnNldExheW91dERhdGEoZGF0YSk7CgkJYXV0b1B1Ymxpc2hMb2NhbC5zZXRTZWxlY3Rpb24ocHJlZmVyZW5jZXMuZ2V0QXV0b1B1Ymxpc2hMb2NhbCgpKTsKCQkvL1dvcmtiZW5jaEhlbHAuc2V0SGVscChzYXZlUHJvbXB0LCBDb250ZXh0SWRzLik7CgkJCgkJYXV0b1B1Ymxpc2hMb2NhbFRpbWUgPSBuZXcgU3Bpbm5lcihjb21wb3NpdGUsIFNXVC5CT1JERVIpOwoJCWF1dG9QdWJsaXNoTG9jYWxUaW1lLnNldE1pbmltdW0oMCk7CgkJYXV0b1B1Ymxpc2hMb2NhbFRpbWUuc2V0TWF4aW11bSgxMjApOwoJCWF1dG9QdWJsaXNoTG9jYWxUaW1lLnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5nZXRBdXRvUHVibGlzaExvY2FsVGltZSgpKTsKCQlhdXRvUHVibGlzaExvY2FsVGltZS5zZXRFbmFibGVkKGF1dG9QdWJsaXNoTG9jYWwuZ2V0U2VsZWN0aW9uKCkpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9FTkQpOwoJCWRhdGEud2lkdGhIaW50ID0gNzU7CgkJYXV0b1B1Ymxpc2hMb2NhbFRpbWUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkKCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChjb21wb3NpdGUsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZkF1dG9QdWJsaXNoU2Vjb25kcyIpKTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRU5EKTsKCQlsYWJlbC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCWF1dG9QdWJsaXNoTG9jYWwuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCWF1dG9QdWJsaXNoTG9jYWxUaW1lLnNldEVuYWJsZWQoYXV0b1B1Ymxpc2hMb2NhbC5nZXRTZWxlY3Rpb24oKSk7CgkJCX0KCQl9KTsKCQkKCQlhdXRvUHVibGlzaFJlbW90ZSA9IG5ldyBCdXR0b24oY29tcG9zaXRlLCBTV1QuQ0hFQ0spOwoJCWF1dG9QdWJsaXNoUmVtb3RlLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmQXV0b1B1Ymxpc2hSZW1vdGUiKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCWF1dG9QdWJsaXNoUmVtb3RlLnNldExheW91dERhdGEoZGF0YSk7CgkJYXV0b1B1Ymxpc2hSZW1vdGUuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmdldEF1dG9QdWJsaXNoUmVtb3RlKCkpOwoJCS8vV29ya2JlbmNoSGVscC5zZXRIZWxwKGF1dG9QdWJsaXNoUmVtb3RlLCBDb250ZXh0SWRzLik7CgkJCgkJYXV0b1B1Ymxpc2hSZW1vdGVUaW1lID0gbmV3IFNwaW5uZXIoY29tcG9zaXRlLCBTV1QuQk9SREVSKTsKCQlhdXRvUHVibGlzaExvY2FsVGltZS5zZXRNaW5pbXVtKDApOwoJCWF1dG9QdWJsaXNoTG9jYWxUaW1lLnNldE1heGltdW0oMTIwKTsKCQlhdXRvUHVibGlzaFJlbW90ZVRpbWUuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmdldEF1dG9QdWJsaXNoUmVtb3RlVGltZSgpKTsKCQlhdXRvUHVibGlzaFJlbW90ZVRpbWUuc2V0RW5hYmxlZChhdXRvUHVibGlzaFJlbW90ZS5nZXRTZWxlY3Rpb24oKSk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwpOwoJCWRhdGEud2lkdGhIaW50ID0gNzU7CgkJYXV0b1B1Ymxpc2hSZW1vdGVUaW1lLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJYXV0b1B1Ymxpc2hSZW1vdGUuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCWF1dG9QdWJsaXNoUmVtb3RlVGltZS5zZXRFbmFibGVkKGF1dG9QdWJsaXNoUmVtb3RlLmdldFNlbGVjdGlvbigpKTsKCQkJfQoJCX0pOwoJCQoJCWxhYmVsID0gbmV3IExhYmVsKGNvbXBvc2l0ZSwgU1dULk5PTkUpOwoJCWxhYmVsLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmQXV0b1B1Ymxpc2hTZWNvbmRzIikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9FTkQpOwoJCWxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJYXV0b1Jlc3RhcnQgPSBuZXcgQnV0dG9uKGNvbXBvc2l0ZSwgU1dULkNIRUNLKTsKCQlhdXRvUmVzdGFydC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZkF1dG9SZXN0YXJ0IikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gNDsKCQlhdXRvUmVzdGFydC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWF1dG9SZXN0YXJ0LnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5pc0F1dG9SZXN0YXJ0aW5nKCkpOwoJCXdocy5zZXRIZWxwKGF1dG9SZXN0YXJ0LCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTF9BVVRPX1JFU1RBUlQpOwoJCQoJCXByb21wdElycmV2ZXJzaWJsZSA9IG5ldyBCdXR0b24oY29tcG9zaXRlLCBTV1QuQ0hFQ0spOwoJCXByb21wdElycmV2ZXJzaWJsZS5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZlByb21wdElycmV2ZXJzaWJsZSIpKTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDQ7CgkJcHJvbXB0SXJyZXZlcnNpYmxlLnNldExheW91dERhdGEoZGF0YSk7CgkJcHJvbXB0SXJyZXZlcnNpYmxlLnNldFNlbGVjdGlvbih1aVByZWZlcmVuY2VzLmdldFByb21wdEJlZm9yZUlycmV2ZXJzaWJsZUNoYW5nZSgpKTsKCQl3aHMuc2V0SGVscChwcm9tcHRJcnJldmVyc2libGUsIENvbnRleHRJZHMuUFJFRl9HRU5FUkFMX1BST01QVF9JUlJFVkVSU0lCTEUpOwoJCQoJCXNob3dPbkFjdGl2aXR5ID0gbmV3IEJ1dHRvbihjb21wb3NpdGUsIFNXVC5DSEVDSyk7CgkJc2hvd09uQWN0aXZpdHkuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXByZWZTaG93T25BY3Rpdml0eSIpKTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkhPUklaT05UQUxfQUxJR05fRklMTCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDQ7CgkJc2hvd09uQWN0aXZpdHkuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQlzaG93T25BY3Rpdml0eS5zZXRTZWxlY3Rpb24odWlQcmVmZXJlbmNlcy5nZXRTaG93T25BY3Rpdml0eSgpKTsKCQl3aHMuc2V0SGVscChzaG93T25BY3Rpdml0eSwgQ29udGV4dElkcy5QUkVGX0dFTkVSQUxfU0hPV19PTl9BQ1RJVklUWSk7CgkJCgkJY3JlYXRlSW5Xb3Jrc3BhY2UgPSBuZXcgQnV0dG9uKGNvbXBvc2l0ZSwgU1dULkNIRUNLKTsKCQljcmVhdGVJbldvcmtzcGFjZS5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZkNyZWF0ZUluV29ya3NwYWNlIikpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gNDsKCQljcmVhdGVJbldvcmtzcGFjZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWNyZWF0ZUluV29ya3NwYWNlLnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5pc0NyZWF0ZVJlc291cmNlc0luV29ya3NwYWNlKCkpOwoJCXdocy5zZXRIZWxwKGNyZWF0ZUluV29ya3NwYWNlLCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTF9DUkVBVEVfSU5fV09SS1NQQUNFKTsKCQkKCQkvLyBzYXZlIGVkaXRvcnMgZ3JvdXAKCQlHcm91cCBzYXZlRWRpdG9yR3JvdXAgPSBuZXcgR3JvdXAoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJc2F2ZUVkaXRvckdyb3VwLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmU2F2ZUVkaXRvcnNHcm91cCIpKTsKCQkKCQlsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5udW1Db2x1bW5zID0gMzsKCQlzYXZlRWRpdG9yR3JvdXAuc2V0TGF5b3V0KGxheW91dCk7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSA0OwoJCXNhdmVFZGl0b3JHcm91cC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCXNhdmVOZXZlciA9IG5ldyBCdXR0b24oc2F2ZUVkaXRvckdyb3VwLCBTV1QuUkFESU8pOwoJCXNhdmVOZXZlci5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZlNhdmVFZGl0b3JzTmV2ZXIiKSk7CgkJc2F2ZU5ldmVyLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBldmVudCkgewoJCQkJc2F2ZUVkaXRvcnMgPSBTZXJ2ZXJVSVByZWZlcmVuY2VzLlNBVkVfRURJVE9SU19ORVZFUjsKCQkJfQoJCX0pOwoJCXdocy5zZXRIZWxwKHNhdmVOZXZlciwgQ29udGV4dElkcy5QUkVGX0dFTkVSQUxfU0FWRV9FRElUT1JTKTsKCQkKCQlzYXZlUHJvbXB0ID0gbmV3IEJ1dHRvbihzYXZlRWRpdG9yR3JvdXAsIFNXVC5SQURJTyk7CgkJc2F2ZVByb21wdC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZlNhdmVFZGl0b3JzUHJvbXB0IikpOwoJCXNhdmVQcm9tcHQuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlzYXZlRWRpdG9ycyA9IFNlcnZlclVJUHJlZmVyZW5jZXMuU0FWRV9FRElUT1JTX1BST01QVDsKCQkJfQoJCX0pOwoJCXdocy5zZXRIZWxwKHNhdmVQcm9tcHQsIENvbnRleHRJZHMuUFJFRl9HRU5FUkFMX1NBVkVfRURJVE9SUyk7CgkJCgkJc2F2ZUF1dG8gPSBuZXcgQnV0dG9uKHNhdmVFZGl0b3JHcm91cCwgU1dULlJBRElPKTsKCQlzYXZlQXV0by5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZlNhdmVFZGl0b3JzQXV0b3NhdmUiKSk7CgkJc2F2ZUF1dG8uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlzYXZlRWRpdG9ycyA9IFNlcnZlclVJUHJlZmVyZW5jZXMuU0FWRV9FRElUT1JTX0FVVE87CgkJCX0KCQl9KTsKCQl3aHMuc2V0SGVscChzYXZlQXV0bywgQ29udGV4dElkcy5QUkVGX0dFTkVSQUxfU0FWRV9FRElUT1JTKTsKCQkKCQlsYWJlbCA9IG5ldyBMYWJlbChjb21wb3NpdGUsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZk1hY2hpbmVTcGVlZCIpKTsKCQkKCQltYWNoaW5lU3BlZWRDb21ibyA9IG5ldyBDb21ibyhjb21wb3NpdGUsIFNXVC5SRUFEX09OTFkpOwoJCVN0cmluZ1tdIGl0ZW1zID0gbmV3IFN0cmluZ1tdIHsKCQkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmTWFjaGluZVNwZWVkVmVyeVNsb3ciKSwKCQkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmTWFjaGluZVNwZWVkU2xvdyIpLAoJCQlTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXByZWZNYWNoaW5lU3BlZWRBdmVyYWdlIiksCgkJCVNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcHJlZk1hY2hpbmVTcGVlZEZhc3QiKSwKCQkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVwcmVmTWFjaGluZVNwZWVkVmVyeUZhc3QiKQoJCX07CgkJbWFjaGluZVNwZWVkQ29tYm8uc2V0SXRlbXMoaXRlbXMpOwoJCW1hY2hpbmVTcGVlZENvbWJvLnNlbGVjdChwcmVmZXJlbmNlcy5nZXRNYWNoaW5lU3BlZWQoKSAvIDIpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQltYWNoaW5lU3BlZWRDb21iby5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCS8vd2hzLnNldEhlbHAobWFjaGluZVNwZWVkU2xpZGVyLCBDb250ZXh0SWRzLlBSRUZfR0VORVJBTF9QUk9NUFRfSVJSRVZFUlNJQkxFKTsKCQkKCQlzZXRTYXZlRWRpdG9yU3RhdHVzKHVpUHJlZmVyZW5jZXMuZ2V0U2F2ZUVkaXRvcnMoKSk7CgkJCgkJRGlhbG9nLmFwcGx5RGlhbG9nRm9udChjb21wb3NpdGUpOwoJCgkJcmV0dXJuIGNvbXBvc2l0ZTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgc2V0U2F2ZUVkaXRvclN0YXR1cyhieXRlIHN0YXR1cykgewoJCXNhdmVFZGl0b3JzID0gc3RhdHVzOwoJCXNhdmVOZXZlci5zZXRTZWxlY3Rpb24oc2F2ZUVkaXRvcnMgPT0gU2VydmVyVUlQcmVmZXJlbmNlcy5TQVZFX0VESVRPUlNfTkVWRVIpOwoJCXNhdmVQcm9tcHQuc2V0U2VsZWN0aW9uKHNhdmVFZGl0b3JzID09IFNlcnZlclVJUHJlZmVyZW5jZXMuU0FWRV9FRElUT1JTX1BST01QVCk7CgkJc2F2ZUF1dG8uc2V0U2VsZWN0aW9uKHNhdmVFZGl0b3JzID09IFNlcnZlclVJUHJlZmVyZW5jZXMuU0FWRV9FRElUT1JTX0FVVE8pOyAKCX0KCQoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGlzIHByZWZlcmVuY2UgcGFnZSB1c2luZyB0aGUgcGFzc2VkIHdvcmtiZW5jaC4KCSAqCgkgKiBAcGFyYW0gd29ya2JlbmNoIHRoZSBjdXJyZW50IHdvcmtiZW5jaAoJICovCglwdWJsaWMgdm9pZCBpbml0KElXb3JrYmVuY2ggd29ya2JlbmNoKSB7CgkJLy8gZG8gbm90aGluZwoJfQoJCgkvKioKCSAqIFBlcmZvcm1zIHNwZWNpYWwgcHJvY2Vzc2luZyB3aGVuIHRoaXMgcGFnZSdzIERlZmF1bHRzIGJ1dHRvbiBoYXMgYmVlbiBwcmVzc2VkLgoJICovCglwcm90ZWN0ZWQgdm9pZCBwZXJmb3JtRGVmYXVsdHMoKSB7CgkJYXV0b1Jlc3RhcnQuc2V0U2VsZWN0aW9uKHByZWZlcmVuY2VzLmlzRGVmYXVsdEF1dG9SZXN0YXJ0aW5nKCkpOwoJCXB1Ymxpc2hCZWZvcmVTdGFydC5zZXRTZWxlY3Rpb24ocHJlZmVyZW5jZXMuaXNEZWZhdWx0QXV0b1B1Ymxpc2hpbmcoKSk7CgkJcHJvbXB0SXJyZXZlcnNpYmxlLnNldFNlbGVjdGlvbih1aVByZWZlcmVuY2VzLmdldERlZmF1bHRQcm9tcHRCZWZvcmVJcnJldmVyc2libGVDaGFuZ2UoKSk7CgkJc2hvd09uQWN0aXZpdHkuc2V0U2VsZWN0aW9uKHVpUHJlZmVyZW5jZXMuZ2V0RGVmYXVsdFNob3dPbkFjdGl2aXR5KCkpOwoJCWNyZWF0ZUluV29ya3NwYWNlLnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5pc0RlZmF1bHRDcmVhdGVSZXNvdXJjZXNJbldvcmtzcGFjZSgpKTsKCQkKCQlhdXRvUHVibGlzaExvY2FsLnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5nZXREZWZhdWx0QXV0b1B1Ymxpc2hMb2NhbCgpKTsKCQlhdXRvUHVibGlzaExvY2FsVGltZS5zZXRTZWxlY3Rpb24ocHJlZmVyZW5jZXMuZ2V0RGVmYXVsdEF1dG9QdWJsaXNoTG9jYWxUaW1lKCkpOwoJCWF1dG9QdWJsaXNoUmVtb3RlLnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5nZXREZWZhdWx0QXV0b1B1Ymxpc2hSZW1vdGUoKSk7CgkJYXV0b1B1Ymxpc2hSZW1vdGVUaW1lLnNldFNlbGVjdGlvbihwcmVmZXJlbmNlcy5nZXREZWZhdWx0QXV0b1B1Ymxpc2hSZW1vdGVUaW1lKCkpOwoJCQoJCW1hY2hpbmVTcGVlZENvbWJvLnNlbGVjdChwcmVmZXJlbmNlcy5nZXREZWZhdWx0TWFjaGluZVNwZWVkKCkgLyAyKTsKCQkKCQlzZXRTYXZlRWRpdG9yU3RhdHVzKHVpUHJlZmVyZW5jZXMuZ2V0RGVmYXVsdFNhdmVFZGl0b3JzKCkpOwoJCgkJc3VwZXIucGVyZm9ybURlZmF1bHRzKCk7Cgl9CgoJLyoqCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmpmYWNlLnByZWZlcmVuY2UuSVByZWZlcmVuY2VQYWdlI3BlcmZvcm1PaygpCgkgKi8KCXB1YmxpYyBib29sZWFuIHBlcmZvcm1PaygpIHsKCQlwcmVmZXJlbmNlcy5zZXRBdXRvUHVibGlzaGluZyhwdWJsaXNoQmVmb3JlU3RhcnQuZ2V0U2VsZWN0aW9uKCkpOwoJCXByZWZlcmVuY2VzLnNldEF1dG9SZXN0YXJ0aW5nKGF1dG9SZXN0YXJ0LmdldFNlbGVjdGlvbigpKTsKCQl1aVByZWZlcmVuY2VzLnNldFNhdmVFZGl0b3JzKHNhdmVFZGl0b3JzKTsKCQl1aVByZWZlcmVuY2VzLnNldFByb21wdEJlZm9yZUlycmV2ZXJzaWJsZUNoYW5nZShwcm9tcHRJcnJldmVyc2libGUuZ2V0U2VsZWN0aW9uKCkpOwoJCXVpUHJlZmVyZW5jZXMuc2V0U2hvd09uQWN0aXZpdHkoc2hvd09uQWN0aXZpdHkuZ2V0U2VsZWN0aW9uKCkpOwoJCXByZWZlcmVuY2VzLnNldENyZWF0ZVJlc291cmNlc0luV29ya3NwYWNlKGNyZWF0ZUluV29ya3NwYWNlLmdldFNlbGVjdGlvbigpKTsKCQkKCQlwcmVmZXJlbmNlcy5zZXRBdXRvUHVibGlzaExvY2FsKGF1dG9QdWJsaXNoTG9jYWwuZ2V0U2VsZWN0aW9uKCkpOwoJCXByZWZlcmVuY2VzLnNldEF1dG9QdWJsaXNoTG9jYWxUaW1lKGF1dG9QdWJsaXNoTG9jYWxUaW1lLmdldFNlbGVjdGlvbigpKTsKCQlwcmVmZXJlbmNlcy5zZXRBdXRvUHVibGlzaFJlbW90ZShhdXRvUHVibGlzaFJlbW90ZS5nZXRTZWxlY3Rpb24oKSk7CgkJcHJlZmVyZW5jZXMuc2V0QXV0b1B1Ymxpc2hSZW1vdGVUaW1lKGF1dG9QdWJsaXNoUmVtb3RlVGltZS5nZXRTZWxlY3Rpb24oKSk7CgkJCgkJcHJlZmVyZW5jZXMuc2V0TWFjaGluZVNwZWVkKG1hY2hpbmVTcGVlZENvbWJvLmdldFNlbGVjdGlvbkluZGV4KCkgKiAyKTsKCQoJCS8vIGF1dG8gcmVzdGFydCBhbnkgc2VydmVycyB0aGF0IGFyZSByZWFkeSBmb3IgcmVzdGFydAoJCWlmIChhdXRvUmVzdGFydC5nZXRTZWxlY3Rpb24oKSkKCQkJYXV0b1Jlc3RhcnRBbGwoKTsKCQoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogQXV0b21hdGljYWxseSByZXN0YXJ0IGFueSBzZXJ2ZXJzIHRoYXQgcmVxdWlyZSBpdC4KCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGF1dG9SZXN0YXJ0QWxsKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIkF1dG8gcmVzdGFydGluZyBhbGwgZGlydHkgc2VydmVycyIpOwoJCgkJSVNlcnZlcltdIHNlcnZlcnMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlcnMoKTsKCQlpZiAoc2VydmVycyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gc2VydmVycy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJU2VydmVyIHNlcnZlciA9IHNlcnZlcnNbaV07CgkJCQlpZiAoc2VydmVyLmdldFNlcnZlclJlc3RhcnRTdGF0ZSgpKSB7CgkJCQkJU3RyaW5nIG1vZGUgPSBzZXJ2ZXIuZ2V0TW9kZSgpOwoJCQkJCWlmIChzZXJ2ZXIuY2FuUmVzdGFydChtb2RlKS5pc09LKCkpCgkJCQkJCXRyeSB7CgkJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJBdHRlbXB0aW5nIHRvIGF1dG8gcmVzdGFydCAiICsgc2VydmVyLmdldE5hbWUoKSk7CgkJCQkJCQlzZXJ2ZXIucmVzdGFydChtb2RlKTsKCQkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIHJlc3RhcnRpbmc6ICIgKyBzZXJ2ZXIsIGUpOwoJCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9Cn0=