cGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMgSUJNIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIKAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUHJvamVjdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5Db3JlRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklQcm9qZWN0TW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5TZXJ2ZXJVSVV0aWw7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25BZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25FdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uTGlzdGVuZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tYm87CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKCi8qKgogKiBEaWFsb2cgdGhhdCBwcm9tcHRzIGEgdXNlciB0byBjaGFuZ2UgdGhlIHRhcmdldCBydW50aW1lLgogKi8KcHVibGljIGNsYXNzIFJ1bnRpbWVUYXJnZXRDb21wb3NpdGUgewoJcHVibGljIGludGVyZmFjZSBSdW50aW1lU2VsZWN0aW9uTGlzdGVuZXIgewoJCXB1YmxpYyB2b2lkIHJ1bnRpbWVTZWxlY3RlZChJUnVudGltZSBydW50aW1lKTsKCX0KCglwcm90ZWN0ZWQgSVByb2plY3QgcHJvamVjdDsKCXByb3RlY3RlZCBJUHJvamVjdFByb3BlcnRpZXMgcHJvcHM7Cglwcm90ZWN0ZWQgSVJ1bnRpbWUgY3VycmVudFJ1bnRpbWU7Cglwcm90ZWN0ZWQgSVJ1bnRpbWUgbmV3UnVudGltZTsKCXByb3RlY3RlZCBMaXN0IHRhcmdldHM7Cglwcm90ZWN0ZWQgU3RyaW5nW10gaXRlbXM7Cglwcm90ZWN0ZWQgUnVudGltZVNlbGVjdGlvbkxpc3RlbmVyIGxpc3RlbmVyOwoJCglwcm90ZWN0ZWQgTGlzdCBjaGlsZFByb2plY3RzOwoJcHJvdGVjdGVkIGJvb2xlYW4gc2V0Q2hpbGRyZW4gPSB0cnVlOwoJcHJvdGVjdGVkIGludCBvZmZzZXQgPSAwOwoKCS8qKgoJICogUnVudGltZVRhcmdldENvbXBvc2l0ZSBjb25zdHJ1Y3RvciBjb21tZW50LgoJICogQHBhcmFtIHBhcmVudCBDb21wb3NpdGUKCSAqIEBwYXJhbSBwcm9qZWN0IElQcm9qZWN0CgkgKi8KCXB1YmxpYyBSdW50aW1lVGFyZ2V0Q29tcG9zaXRlKENvbXBvc2l0ZSBwYXJlbnQsIElQcm9qZWN0IHByb2plY3QpIHsKCQl0aGlzLnByb2plY3QgPSBwcm9qZWN0OwoJCXByb3BzID0gU2VydmVyQ29yZS5nZXRQcm9qZWN0UHJvcGVydGllcyhwcm9qZWN0KTsKCQljdXJyZW50UnVudGltZSA9IHByb3BzLmdldFJ1bnRpbWVUYXJnZXQoKTsKCQlpZiAoY3VycmVudFJ1bnRpbWUgPT0gbnVsbCkKCQkJb2Zmc2V0ID0gMTsKCQkKCQkvLyBnZXQgY2hpbGQgbW9kdWxlcwoJCUlQcm9qZWN0TW9kdWxlIHByb2plY3RNb2R1bGUgPSBTZXJ2ZXJVdGlsLmdldE1vZHVsZVByb2plY3QocHJvamVjdCk7CgkJY2hpbGRQcm9qZWN0cyA9IG5ldyBBcnJheUxpc3QoKTsKCQlpZiAocHJvamVjdE1vZHVsZSAhPSBudWxsKSB7CgkJCUxpc3QgY2hpbGRyZW4gPSBuZXcgQXJyYXlMaXN0KCk7CgkJCUlNb2R1bGVbXSBjaGlsZCA9IHByb2plY3RNb2R1bGUuZ2V0Q2hpbGRNb2R1bGVzKCk7CgkJCWlmIChjaGlsZCAhPSBudWxsKSB7CgkJCQlpbnQgc2l6ZSA9IGNoaWxkLmxlbmd0aDsKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQoJCQkJCWNoaWxkcmVuLmFkZChjaGlsZFtpXSk7CgkJCQlpbnQgYSA9IDA7CgkJCQl3aGlsZSAoYSA8IGNoaWxkcmVuLnNpemUoKSkgewoJCQkJCUlNb2R1bGUgbW9kdWxlID0gKElNb2R1bGUpIGNoaWxkcmVuLmdldChhKTsKCQkJCQlJTW9kdWxlW10gY2hpbGQyID0gbW9kdWxlLmdldENoaWxkTW9kdWxlcygpOwoJCQkJCWlmIChjaGlsZDIgIT0gbnVsbCkgewoJCQkJCQlzaXplID0gY2hpbGQyLmxlbmd0aDsKCQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspCgkJCQkJCQljaGlsZHJlbi5hZGQoY2hpbGQyW2ldKTsKCQkJCQl9CgkJCQkJYSsrOwoJCQkJfQoJCQl9CgkJCQoJCQlJdGVyYXRvciBpdGVyYXRvciA9IGNoaWxkcmVuLml0ZXJhdG9yKCk7CgkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCUlNb2R1bGUgbW9kdWxlID0gKElNb2R1bGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCWlmIChtb2R1bGUgaW5zdGFuY2VvZiBJUHJvamVjdE1vZHVsZSkKCQkJCQljaGlsZFByb2plY3RzLmFkZChtb2R1bGUpOwoJCQl9CgkJfQoJCQoJCWNyZWF0ZUNvbnRlbnRzKHBhcmVudCk7Cgl9CgkKCS8qKgoJICogUnVudGltZVRhcmdldENvbXBvc2l0ZSBjb25zdHJ1Y3RvciBjb21tZW50LgoJICogQHBhcmFtIHBhcmVudFNoZWxsIG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsCgkgKiBAcGFyYW0gcHJvamVjdCBJUHJvamVjdAoJICovCglwdWJsaWMgUnVudGltZVRhcmdldENvbXBvc2l0ZShDb21wb3NpdGUgcGFyZW50LCBJUHJvamVjdCBwcm9qZWN0LCBSdW50aW1lU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQl0aGlzKHBhcmVudCwgcHJvamVjdCk7CgkJdGhpcy5saXN0ZW5lciA9IGxpc3RlbmVyOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGNyZWF0ZUNvbnRlbnRzKGZpbmFsIENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChwYXJlbnQsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcnVudGltZVRhcmdldENvbWJvIikpOwoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9GSUxMKTsKCQlsYWJlbC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCWZpbmFsIENvbWJvIGNvbWJvID0gbmV3IENvbWJvKHBhcmVudCwgU1dULkRST1BfRE9XTiB8IFNXVC5SRUFEX09OTFkpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQljb21iby5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCWludCBzZWwgPSB1cGRhdGVSdW50aW1lcygpOwoJCWNvbWJvLnNldEl0ZW1zKGl0ZW1zKTsKCQlpZiAoaXRlbXMubGVuZ3RoID09IDApCgkJCWNvbWJvLnNldEVuYWJsZWQoZmFsc2UpOwoJCWVsc2UgewoJCQljb21iby5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCQlpbnQgc2VsZWN0ID0gY29tYm8uZ2V0U2VsZWN0aW9uSW5kZXgoKTsKCQkJCQlpZiAob2Zmc2V0ID4gMCAmJiBzZWxlY3QgPT0gMCkKCQkJCQkJbmV3UnVudGltZSA9IG51bGw7CgkJCQkJZWxzZQoJCQkJCQluZXdSdW50aW1lID0gKElSdW50aW1lKSB0YXJnZXRzLmdldChzZWxlY3QgLSBvZmZzZXQpOwoJCQkJCWlmIChsaXN0ZW5lciAhPSBudWxsKQoJCQkJCQlsaXN0ZW5lci5ydW50aW1lU2VsZWN0ZWQobmV3UnVudGltZSk7CgkJCQl9CgkJCX0pOwoJCQlpZiAoc2VsID49IDApIHsKCQkJCWNvbWJvLnNlbGVjdChzZWwpOwoJCQkJaWYgKG9mZnNldCA9PSAwIHx8IHNlbCA+IDApCgkJCQkJbmV3UnVudGltZSA9IChJUnVudGltZSkgdGFyZ2V0cy5nZXQoc2VsIC0gb2Zmc2V0KTsKCQkJfSBlbHNlCgkJCQljb21iby5zZWxlY3QoMCk7CgkJfQoKCQlmaW5hbCBJUHJvamVjdE1vZHVsZSBwcm9qZWN0TW9kdWxlID0gU2VydmVyVXRpbC5nZXRNb2R1bGVQcm9qZWN0KHByb2plY3QpOwoJCQoJCUJ1dHRvbiBidXR0b24gPSBTV1RVdGlsLmNyZWF0ZUJ1dHRvbihwYXJlbnQsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcnVudGltZVRhcmdldE5ld1J1bnRpbWUiKSk7CgkJYnV0dG9uLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlTdHJpbmcgY3VycmVudFJ1bnRpbWUyID0gY29tYm8uZ2V0VGV4dCgpOwoJCQkJU3RyaW5nIHR5cGUgPSBudWxsOwoJCQkJU3RyaW5nIHZlcnNpb24gPSBudWxsOwoJCQkJaWYgKHByb2plY3RNb2R1bGUgIT0gbnVsbCkgewoJCQkJCXR5cGUgPSBwcm9qZWN0TW9kdWxlLmdldFR5cGUoKTsKCQkJCQl2ZXJzaW9uID0gcHJvamVjdE1vZHVsZS5nZXRWZXJzaW9uKCk7CgkJCQl9CgkJCQlpZiAoU2VydmVyVUlVdGlsLnNob3dOZXdSdW50aW1lV2l6YXJkKHBhcmVudC5nZXRTaGVsbCgpLCB0eXBlLCB2ZXJzaW9uKSkgewoJCQkJCWludCBzZWwyID0gdXBkYXRlUnVudGltZXMoKTsKCQkJCQljb21iby5zZXRJdGVtcyhpdGVtcyk7CgkJCQkJY29tYm8uc2V0VGV4dChjdXJyZW50UnVudGltZTIpOwoJCQkJCWlmIChjb21iby5nZXRTZWxlY3Rpb25JbmRleCgpID09IC0xKQoJCQkJCQljb21iby5zZWxlY3Qoc2VsMik7CgkJCQl9CgkJCX0KCQl9KTsKCQkKCQkvLyBjaGlsZCBtb2R1bGUgc2VsZWN0aW9uCgkJaWYgKCFjaGlsZFByb2plY3RzLmlzRW1wdHkoKSkgewoJCQlmaW5hbCBCdXR0b24gaW5jbHVkZUNoaWxkcmVuID0gbmV3IEJ1dHRvbihwYXJlbnQsIFNXVC5DSEVDSyk7CgkJCWluY2x1ZGVDaGlsZHJlbi5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcnVudGltZVRhcmdldENoaWxkcmVuIikpOwoJCQlkYXRhID0gbmV3IEdyaWREYXRhKCk7CgkJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCQlpbmNsdWRlQ2hpbGRyZW4uc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJaW5jbHVkZUNoaWxkcmVuLnNldFNlbGVjdGlvbih0cnVlKTsKCQkJCgkJCWluY2x1ZGVDaGlsZHJlbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7CgkJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQkJc2V0Q2hpbGRyZW4gPSBpbmNsdWRlQ2hpbGRyZW4uZ2V0U2VsZWN0aW9uKCk7CgkJCQl9CgoJCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCQl3aWRnZXRTZWxlY3RlZChlKTsKCQkJCX0KCQkJfSk7CgkJfQoJfQoJCglwcm90ZWN0ZWQgaW50IHVwZGF0ZVJ1bnRpbWVzKCkgewoJCUlQcm9qZWN0TW9kdWxlIHBtID0gU2VydmVyVXRpbC5nZXRNb2R1bGVQcm9qZWN0KHByb2plY3QpOwoJCWlmIChwbSAhPSBudWxsKQoJCQl0YXJnZXRzID0gU2VydmVyVXRpbC5nZXRSdW50aW1lcyhwbS5nZXRUeXBlKCksIHBtLmdldFZlcnNpb24oKSk7CgoJCWl0ZW1zID0gbmV3IFN0cmluZ1swXTsKCQlpbnQgc2VsID0gLTE7CgkJaWYgKHRhcmdldHMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHRhcmdldHMuc2l6ZSgpOwoJCQlpdGVtcyA9IG5ldyBTdHJpbmdbc2l6ZSArIG9mZnNldF07CgkJCWlmIChvZmZzZXQgPiAwKSB7CgkJCQlpdGVtc1swXSA9IFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcnVudGltZVRhcmdldE5vbmUiKTsKCQkJCXNlbCA9IDA7CgkJCX0KCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlSdW50aW1lIHRhcmdldCA9IChJUnVudGltZSkgdGFyZ2V0cy5nZXQoaSk7CgkJCQlpdGVtc1tpK29mZnNldF0gPSB0YXJnZXQuZ2V0TmFtZSgpOwoJCQkJaWYgKHRhcmdldC5lcXVhbHMoY3VycmVudFJ1bnRpbWUpKQoJCQkJCXNlbCA9IGk7CgkJCX0KCQl9CgkJcmV0dXJuIHNlbDsKCX0KCQoJcHVibGljIElSdW50aW1lIGdldFNlbGVjdGVkUnVudGltZSgpIHsKCQlyZXR1cm4gbmV3UnVudGltZTsKCX0KCQoJcHVibGljIGJvb2xlYW4gaGFzQ2hhbmdlZCgpIHsKCQlpZiAoIWNoaWxkUHJvamVjdHMuaXNFbXB0eSgpKQoJCQlyZXR1cm4gdHJ1ZTsKCQlpZiAobmV3UnVudGltZSA9PSBudWxsKQoJCQlyZXR1cm4gZmFsc2U7CgkJaWYgKG5ld1J1bnRpbWUuZXF1YWxzKGN1cnJlbnRSdW50aW1lKSkKCQkJcmV0dXJuIGZhbHNlOwoJCXJldHVybiB0cnVlOwoJfQoKCXB1YmxpYyB2b2lkIGFwcGx5KElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWlmIChuZXdSdW50aW1lID09IG51bGwgfHwgIW5ld1J1bnRpbWUuZXF1YWxzKHByb3BzLmdldFJ1bnRpbWVUYXJnZXQoKSkpCgkJCXByb3BzLnNldFJ1bnRpbWVUYXJnZXQobmV3UnVudGltZSwgbW9uaXRvcik7CgkJCgkJaWYgKHNldENoaWxkcmVuKSB7CgkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gY2hpbGRQcm9qZWN0cy5pdGVyYXRvcigpOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQlJUHJvamVjdE1vZHVsZSBtb2R1bGUgPSAoSVByb2plY3RNb2R1bGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCUlQcm9qZWN0IHByb2ogPSBtb2R1bGUuZ2V0UHJvamVjdCgpOwoJCQkJcHJvcHMgPSBTZXJ2ZXJDb3JlLmdldFByb2plY3RQcm9wZXJ0aWVzKHByb2opOwoJCQkJCgkJCQlpZiAobmV3UnVudGltZSA9PSBudWxsIHx8ICFuZXdSdW50aW1lLmVxdWFscyhwcm9wcy5nZXRSdW50aW1lVGFyZ2V0KCkpKQoJCQkJCXByb3BzLnNldFJ1bnRpbWVUYXJnZXQobmV3UnVudGltZSwgbW9uaXRvcik7CgkJCX0KCQl9Cgl9Cn0=