LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwud2l6YXJkLnBhZ2U7CgppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5Db3JlRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLkRpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuSU1lc3NhZ2VQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSUxhYmVsUHJvdmlkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25BZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25FdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZERhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWRMYXlvdXQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5CdXR0b247CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5EaXNwbGF5OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGFiZWw7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UcmVlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVHJlZUl0ZW07CmltcG9ydCBvcmcuZWNsaXBzZS51aS5oZWxwLldvcmtiZW5jaEhlbHA7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuU2VydmVyVUlDb3JlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS53aXphcmQuSVdpemFyZEhhbmRsZTsKLyoqCiAqIEEgd2l6YXJkIHBhZ2UgdXNlZCB0byBhZGQgYW5kIHJlbW92ZSBtb2R1bGVzLgogKi8KcHVibGljIGNsYXNzIE1vZGlmeU1vZHVsZXNDb21wb3NpdGUgZXh0ZW5kcyBDb21wb3NpdGUgewoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBJTGFiZWxQcm92aWRlciBzbHAgPSBTZXJ2ZXJVSUNvcmUuZ2V0TGFiZWxQcm92aWRlcigpOwoJCglwcm90ZWN0ZWQgSVdpemFyZEhhbmRsZSB3aXphcmQ7CgkKCXByb3RlY3RlZCBJU2VydmVyQXR0cmlidXRlcyBzZXJ2ZXI7CgoJcHJvdGVjdGVkIE1hcCBjaGlsZE1vZHVsZU1hcCA9IG5ldyBIYXNoTWFwKCk7Cglwcm90ZWN0ZWQgTWFwIHBhcmVudFRyZWVJdGVtTWFwID0gbmV3IEhhc2hNYXAoKTsKCgkvLyBvcmlnaW5hbCBtb2R1bGVzIG9uIHRoZSBzZXJ2ZXIKCXByb3RlY3RlZCBMaXN0IG9yaWdpbmFsTW9kdWxlcyA9IG5ldyBBcnJheUxpc3QoKTsKCQoJLy8gbW9kdWxlcyBhdmFpbGFibGUgdG8gYmUgYWRkZWQgdG8gdGhlIHNlcnZlcgoJcHJvdGVjdGVkIExpc3QgbW9kdWxlcyA9IG5ldyBBcnJheUxpc3QoKTsKCQoJLy8gY3VycmVudCBtb2R1bGVzIG9uIHRoZSBzZXJ2ZXIKCXByb3RlY3RlZCBMaXN0IGRlcGxveWVkID0gbmV3IEFycmF5TGlzdCgpOwoKCXByb3RlY3RlZCBUcmVlIGF2YWlsYWJsZVRyZWU7Cglwcm90ZWN0ZWQgVHJlZSBkZXBsb3llZFRyZWU7CgkKCXByb3RlY3RlZCBCdXR0b24gYWRkLCBhZGRBbGw7Cglwcm90ZWN0ZWQgQnV0dG9uIHJlbW92ZSwgcmVtb3ZlQWxsOwoJCglwcm90ZWN0ZWQgSVRhc2tNb2RlbCB0YXNrTW9kZWw7Cglwcm90ZWN0ZWQgSU1vZHVsZSBuZXdNb2R1bGU7Cglwcm90ZWN0ZWQgSU1vZHVsZSBvcmlnTmV3TW9kdWxlOwoJCglwcm90ZWN0ZWQgTWFwIGVycm9yTWFwOwoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IE1vZGlmeU1vZHVsZXNDb21wb3NpdGUuCgkgKi8KCXB1YmxpYyBNb2RpZnlNb2R1bGVzQ29tcG9zaXRlKENvbXBvc2l0ZSBwYXJlbnQsIElXaXphcmRIYW5kbGUgd2l6YXJkLCBJTW9kdWxlIG1vZHVsZSkgewoJCXN1cGVyKHBhcmVudCwgU1dULk5PTkUpOwoJCXRoaXMud2l6YXJkID0gd2l6YXJkOwoJCW9yaWdOZXdNb2R1bGUgPSBtb2R1bGU7CgkJCQoJCXdpemFyZC5zZXRUaXRsZShTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpek1vZHVsZVRpdGxlIikpOwoJCXdpemFyZC5zZXREZXNjcmlwdGlvbihTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpek1vZHVsZURlc2NyaXB0aW9uIikpOwoJCXdpemFyZC5zZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfV0laQkFOX1NFTEVDVF9TRVJWRVIpKTsKCQkKCQljcmVhdGVDb250cm9sKCk7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFNlcnZlcihJU2VydmVyQXR0cmlidXRlcyBzZXJ2ZXIpIHsKCQlpZiAoc2VydmVyID09IHRoaXMuc2VydmVyKQoJCQlyZXR1cm47CgoJCXRoaXMuc2VydmVyID0gc2VydmVyOwoJCW9yaWdpbmFsTW9kdWxlcyA9IG5ldyBBcnJheUxpc3QoKTsKCQlkZXBsb3llZCA9IG5ldyBBcnJheUxpc3QoKTsKCQltb2R1bGVzID0gbmV3IEFycmF5TGlzdCgpOwoJCQoJCWNoaWxkTW9kdWxlTWFwID0gbmV3IEhhc2hNYXAoKTsKCQkKCQlpZiAoc2VydmVyID09IG51bGwpCgkJCXJldHVybjsKCgkJLy8gZ2V0IGN1cnJlbnRseSBkZXBsb3llZCBtb2R1bGVzCgkJSU1vZHVsZVtdIGN1cnJlbnRNb2R1bGVzID0gc2VydmVyLmdldE1vZHVsZXMobnVsbCk7CgkJaWYgKGN1cnJlbnRNb2R1bGVzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBjdXJyZW50TW9kdWxlcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlvcmlnaW5hbE1vZHVsZXMuYWRkKGN1cnJlbnRNb2R1bGVzW2ldKTsKCQkJCWRlcGxveWVkLmFkZChjdXJyZW50TW9kdWxlc1tpXSk7CgkJCX0KCQl9CgkJCgkJLy8gYWRkIG5ldyBtb2R1bGUKCQluZXdNb2R1bGUgPSBudWxsOwoJCWlmIChvcmlnTmV3TW9kdWxlICE9IG51bGwpIHsKCQkJdHJ5IHsKCQkJCUlNb2R1bGVbXSBwYXJlbnRzID0gc2VydmVyLmdldFBhcmVudE1vZHVsZXMob3JpZ05ld01vZHVsZSwgbnVsbCk7CgkJCQlpZiAocGFyZW50cyAhPSBudWxsICYmIHBhcmVudHMubGVuZ3RoID4gMCkKCQkJCQluZXdNb2R1bGUgPSBwYXJlbnRzWzBdOwoJCQkJZWxzZQoJCQkJCW5ld01vZHVsZSA9IG9yaWdOZXdNb2R1bGU7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGZpbmQgcGFyZW50IG1vZHVsZSIsIGUpOwoJCQkJbmV3TW9kdWxlID0gbnVsbDsKCQkJfQoJCX0KCQlpZiAobmV3TW9kdWxlICE9IG51bGwgJiYgIWRlcGxveWVkLmNvbnRhaW5zKG5ld01vZHVsZSkpCgkJCWRlcGxveWVkLmFkZChuZXdNb2R1bGUpOwoKCQkvLyBnZXQgcmVtYWluaW5nIG1vZHVsZXMKCQllcnJvck1hcCA9IG5ldyBIYXNoTWFwKCk7CgkJSU1vZHVsZVtdIG1vZHVsZXMyID0gU2VydmVyVXRpbC5nZXRNb2R1bGVzKHNlcnZlci5nZXRTZXJ2ZXJUeXBlKCkuZ2V0UnVudGltZVR5cGUoKS5nZXRNb2R1bGVUeXBlcygpKTsKCQlpZiAobW9kdWxlczIgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IG1vZHVsZXMyLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlNb2R1bGUgbW9kdWxlID0gbW9kdWxlczJbaV07CgkJCQlpZiAoIWRlcGxveWVkLmNvbnRhaW5zKG1vZHVsZSkpIHsKCQkJCQl0cnkgewoJCQkJCQlJTW9kdWxlW10gcGFyZW50cyA9IHNlcnZlci5nZXRQYXJlbnRNb2R1bGVzKG1vZHVsZSwgbnVsbCk7CgkJCQkJCWlmIChwYXJlbnRzICE9IG51bGwpIHsKCQkJCQkJCWludCBzaXplMiA9IHBhcmVudHMubGVuZ3RoOwoJCQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQkJCQkJaWYgKHBhcmVudHNbal0uZXF1YWxzKG1vZHVsZSkpIHsKCQkJCQkJCQkJSVN0YXR1cyBzdGF0dXMgPSBzZXJ2ZXIuY2FuTW9kaWZ5TW9kdWxlcyhuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sIG51bGwsIG51bGwpOwoJCQkJCQkJCQlpZiAoc3RhdHVzICE9IG51bGwgJiYgIXN0YXR1cy5pc09LKCkpCgkJCQkJCQkJCQllcnJvck1hcC5wdXQobW9kdWxlLCBzdGF0dXMpOwoJCQkJCQkJCQltb2R1bGVzLmFkZChtb2R1bGUpOwoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCQkJZXJyb3JNYXAucHV0KG1vZHVsZSwgY2UuZ2V0U3RhdHVzKCkpOwoJCQkJCQltb2R1bGVzLmFkZChtb2R1bGUpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJLy8gYnVpbGQgY2hpbGQgbWFwCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBkZXBsb3llZC5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSU1vZHVsZSBtb2R1bGUgPSAoSU1vZHVsZSkgaXRlcmF0b3IubmV4dCgpOwoJCQl0cnkgewoJCQkJSU1vZHVsZVtdIGNoaWxkcmVuID0gc2VydmVyLmdldENoaWxkTW9kdWxlcyhtb2R1bGUsIG51bGwpOwoJCQkJY2hpbGRNb2R1bGVNYXAucHV0KG1vZHVsZSwgY2hpbGRyZW4pOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJLy8gaWdub3JlCgkJCX0KCQl9CgoJCWl0ZXJhdG9yID0gbW9kdWxlcy5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSU1vZHVsZSBtb2R1bGUgPSAoSU1vZHVsZSkgaXRlcmF0b3IubmV4dCgpOwoJCQl0cnkgewoJCQkJSU1vZHVsZVtdIGNoaWxkcmVuID0gc2VydmVyLmdldENoaWxkTW9kdWxlcyhtb2R1bGUsIG51bGwpOwoJCQkJY2hpbGRNb2R1bGVNYXAucHV0KG1vZHVsZSwgY2hpbGRyZW4pOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJLy8gaWdub3JlCgkJCX0KCQl9CgkJCgkJaWYgKGF2YWlsYWJsZVRyZWUgIT0gbnVsbCkKCQkJRGlzcGxheS5nZXREZWZhdWx0KCkuc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoJCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJCXRyeSB7IC8vIHVwZGF0ZSB0cmVlcyBpZiB3ZSBjYW4KCQkJCQkJcGFyZW50VHJlZUl0ZW1NYXAgPSBuZXcgSGFzaE1hcCgpOwoJCQkJCQlmaWxsVHJlZShhdmFpbGFibGVUcmVlLCBtb2R1bGVzKTsKCQkJCQkJZmlsbFRyZWUoZGVwbG95ZWRUcmVlLCBkZXBsb3llZCk7CgkJCQkJCXNldEVuYWJsZW1lbnQoKTsKCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCQkvLyBpZ25vcmUKCQkJCQl9CgkJCQl9CgkJCX0pOwoJCXVwZGF0ZVRhc2tNb2RlbCgpOwoJfQoJCglwdWJsaWMgdm9pZCBzZXRUYXNrTW9kZWwoSVRhc2tNb2RlbCBtb2RlbCkgewoJCXRoaXMudGFza01vZGVsID0gbW9kZWw7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIHRoZSBVSSBvZiB0aGUgcGFnZS4KCSAqCgkgKiBAcGFyYW0gb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlIHBhcmVudAoJICovCglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVDb250cm9sKCkgewoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQuaG9yaXpvbnRhbFNwYWNpbmcgPSBTV1RVdGlsLmNvbnZlcnRIb3Jpem9udGFsRExVc1RvUGl4ZWxzKHRoaXMsIDQpOwoJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSBTV1RVdGlsLmNvbnZlcnRWZXJ0aWNhbERMVXNUb1BpeGVscyh0aGlzLCA0KTsKCQlsYXlvdXQubWFyZ2luV2lkdGggPSAwOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSAwOwoJCWxheW91dC5udW1Db2x1bW5zID0gMzsKCQlzZXRMYXlvdXQobGF5b3V0KTsKCQlzZXRGb250KGdldFBhcmVudCgpLmdldEZvbnQoKSk7CgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKHRoaXMsIENvbnRleHRJZHMuTU9ESUZZX01PRFVMRVNfQ09NUE9TSVRFKTsKCgkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwodGhpcywgU1dULk5PTkUpOwoJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMIHwgR3JpZERhdGEuVkVSVElDQUxfQUxJR05fQkVHSU5OSU5HKTsKCQlkYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQlsYWJlbC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWxhYmVsLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpNb2R1bGVNZXNzYWdlIikpOwoKCQlsYWJlbCA9IG5ldyBMYWJlbCh0aGlzLCBTV1QuTk9ORSk7CgkJbGFiZWwuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpek1vZHVsZUF2YWlsYWJsZUxpc3QiKSk7CgkJCgkJbGFiZWwgPSBuZXcgTGFiZWwodGhpcywgU1dULk5PTkUpOwoJCWxhYmVsLnNldFRleHQoIiIpOwoJCQoJCWxhYmVsID0gbmV3IExhYmVsKHRoaXMsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6TW9kdWxlRGVwbG95ZWRMaXN0IikpOwoKCQlhdmFpbGFibGVUcmVlID0gbmV3IFRyZWUodGhpcywgU1dULkJPUkRFUik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpOwoJCWRhdGEuaGVpZ2h0SGludCA9IDIwMDsKCQlkYXRhLndpZHRoSGludCA9IDE1MDsKCQlhdmFpbGFibGVUcmVlLnNldExheW91dERhdGEoZGF0YSk7CgkJYXZhaWxhYmxlVHJlZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZXZlbnQpIHsKCQkJCXNldEVuYWJsZW1lbnQoKTsKCQkJfQoJCX0pOwoKCQkvLyBzbG9zaCBidXR0b25zCgkJQ29tcG9zaXRlIGNvbXAgPSBuZXcgQ29tcG9zaXRlKHRoaXMsIFNXVC5OT05FKTsKCQlkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCk7CgkJZGF0YS53aWR0aEhpbnQgPSAxMjA7CgkJY29tcC5zZXRMYXlvdXREYXRhKGRhdGEpOwoKCQlsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDU7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDI1OwoJCWxheW91dC52ZXJ0aWNhbFNwYWNpbmcgPSAyMDsKCQljb21wLnNldExheW91dChsYXlvdXQpOwoKCQlhZGQgPSBuZXcgQnV0dG9uKGNvbXAsIFNXVC5QVVNIKTsKCQlhZGQuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpek1vZHVsZUFkZCIpKTsKCQlhZGQuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKSk7CgkJYWRkLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBldmVudCkgewoJCQkJYWRkKGZhbHNlKTsKCQkJfQoJCX0pOwoJCQoJCXJlbW92ZSA9IG5ldyBCdXR0b24oY29tcCwgU1dULlBVU0gpOwoJCXJlbW92ZS5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6TW9kdWxlUmVtb3ZlIikpOwoJCXJlbW92ZS5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCQlyZW1vdmUuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlyZW1vdmUoZmFsc2UpOwoJCQl9CgkJfSk7CgkJCgkJbGFiZWwgPSBuZXcgTGFiZWwoY29tcCwgU1dULk5PTkUpOwoJCWxhYmVsLnNldFRleHQoIiIpOwoJCQoJCWFkZEFsbCA9IG5ldyBCdXR0b24oY29tcCwgU1dULlBVU0gpOwoJCWFkZEFsbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIld2l6TW9kdWxlQWRkQWxsIikpOwoJCWFkZEFsbC5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCQlhZGRBbGwuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGV2ZW50KSB7CgkJCQlhZGQodHJ1ZSk7CgkJCX0KCQl9KTsKCQkKCQlyZW1vdmVBbGwgPSBuZXcgQnV0dG9uKGNvbXAsIFNXVC5QVVNIKTsKCQlyZW1vdmVBbGwuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpek1vZHVsZVJlbW92ZUFsbCIpKTsKCQlyZW1vdmVBbGwuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKSk7CgkJcmVtb3ZlQWxsLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBldmVudCkgewoJCQkJcmVtb3ZlKHRydWUpOwoJCQl9CgkJfSk7CgkJCgkJZGVwbG95ZWRUcmVlID0gbmV3IFRyZWUodGhpcywgU1dULkJPUkRFUik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpOwoJCWRhdGEud2lkdGhIaW50ID0gMTUwOwoJCWRlcGxveWVkVHJlZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWRlcGxveWVkVHJlZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZXZlbnQpIHsKCQkJCXNldEVuYWJsZW1lbnQoKTsKCQkJfQoJCX0pOwoJCQoJCXBhcmVudFRyZWVJdGVtTWFwID0gbmV3IEhhc2hNYXAoKTsKCQlmaWxsVHJlZShhdmFpbGFibGVUcmVlLCBtb2R1bGVzKTsKCQlmaWxsVHJlZShkZXBsb3llZFRyZWUsIGRlcGxveWVkKTsKCQkKCQlzZXRFbmFibGVtZW50KCk7CgkJCgkJYXZhaWxhYmxlVHJlZS5zZXRGb2N1cygpOwoJCQoJCURpYWxvZy5hcHBseURpYWxvZ0ZvbnQodGhpcyk7Cgl9CgkKCXByb3RlY3RlZCB2b2lkIHNldEVuYWJsZW1lbnQoKSB7CgkJYm9vbGVhbiBlbmFibGVkID0gZmFsc2U7CgkJd2l6YXJkLnNldE1lc3NhZ2UobnVsbCwgSU1lc3NhZ2VQcm92aWRlci5OT05FKTsKCQlpZiAoYXZhaWxhYmxlVHJlZS5nZXRJdGVtQ291bnQoKSA+IDApIHsKCQkJdHJ5IHsKCQkJCVRyZWVJdGVtIGl0ZW0gPSBhdmFpbGFibGVUcmVlLmdldFNlbGVjdGlvbigpWzBdOwoJCQkJaXRlbSA9IChUcmVlSXRlbSkgcGFyZW50VHJlZUl0ZW1NYXAuZ2V0KGl0ZW0pOwoJCQkJSU1vZHVsZSBtb2R1bGUgPSAoSU1vZHVsZSkgaXRlbS5nZXREYXRhKCk7CgkJCQkKCQkJCUlTdGF0dXMgc3RhdHVzID0gKElTdGF0dXMpIGVycm9yTWFwLmdldChtb2R1bGUpOwoJCQkJaWYgKG1vZHVsZXMuY29udGFpbnMobW9kdWxlKSkgewoJCQkJCWlmIChzdGF0dXMgPT0gbnVsbCkKCQkJCQkJZW5hYmxlZCA9IHRydWU7CgkJCQkJZWxzZSBpZiAoc3RhdHVzLmdldFNldmVyaXR5KCkgPT0gSVN0YXR1cy5FUlJPUikKCQkJCQkJd2l6YXJkLnNldE1lc3NhZ2Uoc3RhdHVzLmdldE1lc3NhZ2UoKSwgSU1lc3NhZ2VQcm92aWRlci5FUlJPUik7CgkJCQkJZWxzZSBpZiAoc3RhdHVzLmdldFNldmVyaXR5KCkgPT0gSVN0YXR1cy5XQVJOSU5HKQoJCQkJCQl3aXphcmQuc2V0TWVzc2FnZShzdGF0dXMuZ2V0TWVzc2FnZSgpLCBJTWVzc2FnZVByb3ZpZGVyLldBUk5JTkcpOwoJCQkJCWVsc2UgaWYgKHN0YXR1cy5nZXRTZXZlcml0eSgpID09IElTdGF0dXMuSU5GTykKCQkJCQkJd2l6YXJkLnNldE1lc3NhZ2Uoc3RhdHVzLmdldE1lc3NhZ2UoKSwgSU1lc3NhZ2VQcm92aWRlci5JTkZPUk1BVElPTik7CgkJCQl9CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkvLyBpZ25vcmUKCQkJfQoJCX0KCQlhZGQuc2V0RW5hYmxlZChlbmFibGVkKTsKCQlhZGRBbGwuc2V0RW5hYmxlZChhdmFpbGFibGVUcmVlLmdldEl0ZW1Db3VudCgpID4gMCk7CgkJCgkJZW5hYmxlZCA9IGZhbHNlOwoJCWlmIChkZXBsb3llZFRyZWUuZ2V0SXRlbUNvdW50KCkgPiAwKSB7CgkJCXRyeSB7CgkJCQlUcmVlSXRlbSBpdGVtID0gZGVwbG95ZWRUcmVlLmdldFNlbGVjdGlvbigpWzBdOwoJCQkJaXRlbSA9IChUcmVlSXRlbSkgcGFyZW50VHJlZUl0ZW1NYXAuZ2V0KGl0ZW0pOwoJCQkJSU1vZHVsZSBtb2R1bGUgPSAoSU1vZHVsZSkgaXRlbS5nZXREYXRhKCk7CgkJCQlpZiAoZGVwbG95ZWQuY29udGFpbnMobW9kdWxlKSAmJiAhbW9kdWxlLmVxdWFscyhuZXdNb2R1bGUpKQoJCQkJCWVuYWJsZWQgPSB0cnVlOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJLy8gaWdub3JlCgkJCX0KCQl9CgkJcmVtb3ZlLnNldEVuYWJsZWQoZW5hYmxlZCk7CgkJaWYgKG5ld01vZHVsZSA9PSBudWxsKQoJCQlyZW1vdmVBbGwuc2V0RW5hYmxlZChkZXBsb3llZFRyZWUuZ2V0SXRlbUNvdW50KCkgPiAwKTsKCQllbHNlCgkJCXJlbW92ZUFsbC5zZXRFbmFibGVkKGRlcGxveWVkVHJlZS5nZXRJdGVtQ291bnQoKSA+IDEpOwoJfQoKCXByb3RlY3RlZCB2b2lkIGFkZENoaWxkcmVuKFRyZWVJdGVtIGl0ZW0sIElNb2R1bGUgbW9kdWxlKSB7CgkJdHJ5IHsKCQkJSU1vZHVsZVtdIGNoaWxkcmVuID0gKElNb2R1bGVbXSkgY2hpbGRNb2R1bGVNYXAuZ2V0KG1vZHVsZSk7CgkJCWlmIChjaGlsZHJlbiAhPSBudWxsKSB7CgkJCQlpbnQgc2l6ZSA9IGNoaWxkcmVuLmxlbmd0aDsKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQkJSU1vZHVsZSBjaGlsZCA9IGNoaWxkcmVuW2ldOwoJCQkJCVRyZWVJdGVtIGNoaWxkSXRlbSA9IG5ldyBUcmVlSXRlbShpdGVtLCBTV1QuTk9ORSk7CgkJCQkJY2hpbGRJdGVtLnNldFRleHQoc2xwLmdldFRleHQoY2hpbGQpKTsKCQkJCQljaGlsZEl0ZW0uc2V0SW1hZ2Uoc2xwLmdldEltYWdlKGNoaWxkKSk7CgkJCQkJY2hpbGRJdGVtLnNldERhdGEoY2hpbGQpOwoJCQkJCXBhcmVudFRyZWVJdGVtTWFwLnB1dChjaGlsZEl0ZW0sIGl0ZW0pOwoJCQkJCWFkZENoaWxkcmVuKGNoaWxkSXRlbSwgY2hpbGQpOwoJCQkJfQoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJLy8gaWdub3JlCgkJfQoJfQoKCXByb3RlY3RlZCB2b2lkIGZpbGxUcmVlKFRyZWUgdHJlZSwgTGlzdCBtb2R1bGVzMikgewoJCXRyZWUucmVtb3ZlQWxsKCk7CgoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gbW9kdWxlczIuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlNb2R1bGUgbW9kdWxlID0gKElNb2R1bGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJVHJlZUl0ZW0gaXRlbSA9IG5ldyBUcmVlSXRlbSh0cmVlLCBTV1QuTk9ORSk7CgkJCWl0ZW0uc2V0VGV4dChzbHAuZ2V0VGV4dChtb2R1bGUpKTsKCQkJaXRlbS5zZXRJbWFnZShzbHAuZ2V0SW1hZ2UobW9kdWxlKSk7CgkJCWl0ZW0uc2V0RGF0YShtb2R1bGUpOwoJCQlwYXJlbnRUcmVlSXRlbU1hcC5wdXQoaXRlbSwgaXRlbSk7CgkJCWFkZENoaWxkcmVuKGl0ZW0sIG1vZHVsZSk7CgkJfQoJfQoKCXByb3RlY3RlZCB2b2lkIGFkZChib29sZWFuIGFsbCkgewoJCWlmIChhbGwpCgkJCW1vdmVBbGwoYXZhaWxhYmxlVHJlZS5nZXRJdGVtcygpLCB0cnVlKTsKCQllbHNlCgkJCW1vdmVBbGwoYXZhaWxhYmxlVHJlZS5nZXRTZWxlY3Rpb24oKSwgdHJ1ZSk7CgkJdXBkYXRlVGFza01vZGVsKCk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgcmVtb3ZlKGJvb2xlYW4gYWxsKSB7CgkJaWYgKGFsbCkKCQkJbW92ZUFsbChkZXBsb3llZFRyZWUuZ2V0SXRlbXMoKSwgZmFsc2UpOwoJCWVsc2UKCQkJbW92ZUFsbChkZXBsb3llZFRyZWUuZ2V0U2VsZWN0aW9uKCksIGZhbHNlKTsKCQl1cGRhdGVUYXNrTW9kZWwoKTsKCX0KCglwcm90ZWN0ZWQgdm9pZCBtb3ZlQWxsKFRyZWVJdGVtW10gaXRlbXMsIGJvb2xlYW4gYWRkMikgewoJCWludCBzaXplID0gaXRlbXMubGVuZ3RoOwoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlUcmVlSXRlbSBpdGVtID0gKFRyZWVJdGVtKSBwYXJlbnRUcmVlSXRlbU1hcC5nZXQoaXRlbXNbaV0pOwoJCQlJTW9kdWxlIG1vZHVsZSA9IChJTW9kdWxlKSBpdGVtLmdldERhdGEoKTsKCQkJCgkJCWlmICghbGlzdC5jb250YWlucyhtb2R1bGUpKQoJCQkJbGlzdC5hZGQobW9kdWxlKTsKCQl9CgoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gbGlzdC5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSU1vZHVsZSBtb2R1bGUgPSAoSU1vZHVsZSkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoYWRkMikgewoJCQkJbW9kdWxlcy5yZW1vdmUobW9kdWxlKTsKCQkJCWRlcGxveWVkLmFkZChtb2R1bGUpOwoJCQl9IGVsc2UgewoJCQkJbW9kdWxlcy5hZGQobW9kdWxlKTsKCQkJCWRlcGxveWVkLnJlbW92ZShtb2R1bGUpOwoJCQl9CgkJfQoKCQlwYXJlbnRUcmVlSXRlbU1hcCA9IG5ldyBIYXNoTWFwKCk7CgkJZmlsbFRyZWUoYXZhaWxhYmxlVHJlZSwgbW9kdWxlcyk7CgkJZmlsbFRyZWUoZGVwbG95ZWRUcmVlLCBkZXBsb3llZCk7CgoJCXNldEVuYWJsZW1lbnQoKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgdXBkYXRlVGFza01vZGVsKCkgewoJCWlmICh0YXNrTW9kZWwgPT0gbnVsbCkKCQkJcmV0dXJuOwoKCQlNb2R1bGVNYXAgbWFwID0gZ2V0TW9kdWxlTWFwKCk7CgkJaW50IHNpemUgPSBtYXAucGFyZW50TGlzdC5zaXplKCk7CgkJTGlzdFtdIHBhcmVudHMgPSBuZXcgTGlzdFtzaXplXTsKCQltYXAucGFyZW50TGlzdC50b0FycmF5KHBhcmVudHMpOwoJCgkJc2l6ZSA9IG1hcC5wYXJlbnRMaXN0LnNpemUoKTsKCQlJTW9kdWxlW10gbW9kdWxlczIgPSBuZXcgSU1vZHVsZVtzaXplXTsKCQltYXAubW9kdWxlTGlzdC50b0FycmF5KG1vZHVsZXMyKTsKCQkKCQl0YXNrTW9kZWwucHV0T2JqZWN0KElUYXNrTW9kZWwuVEFTS19NT0RVTEVfUEFSRU5UUywgcGFyZW50cyk7CgkJdGFza01vZGVsLnB1dE9iamVjdChJVGFza01vZGVsLlRBU0tfTU9EVUxFUywgbW9kdWxlczIpOwoJCXdpemFyZC51cGRhdGUoKTsKCX0KCgkvKioKCSAqIFJldHVybiB0cnVlIGlmIHRoaXMgcGFnZSBpcyBjb21wbGV0ZS4KCSAqIEByZXR1cm4gYm9vbGVhbgoJICovCglwdWJsaWMgYm9vbGVhbiBpc1BhZ2VDb21wbGV0ZSgpIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglwdWJsaWMgTGlzdCBnZXRNb2R1bGVzVG9SZW1vdmUoKSB7CgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gb3JpZ2luYWxNb2R1bGVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlJTW9kdWxlIG1vZHVsZSA9IChJTW9kdWxlKSBpdGVyYXRvci5uZXh0KCk7CgkJCWlmICghZGVwbG95ZWQuY29udGFpbnMobW9kdWxlKSkKCQkJCWxpc3QuYWRkKG1vZHVsZSk7CgkJfQoJCXJldHVybiBsaXN0OwoJfQoJCglwdWJsaWMgTGlzdCBnZXRNb2R1bGVzVG9BZGQoKSB7CgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gZGVwbG95ZWQuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCUlNb2R1bGUgbW9kdWxlID0gKElNb2R1bGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKCFvcmlnaW5hbE1vZHVsZXMuY29udGFpbnMobW9kdWxlKSkKCQkJCWxpc3QuYWRkKG1vZHVsZSk7CgkJfQoJCXJldHVybiBsaXN0OwoJfQoJCglwdWJsaWMgY2xhc3MgTW9kdWxlTWFwIHsKCQlwdWJsaWMgTGlzdCBwYXJlbnRMaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCXB1YmxpYyBMaXN0IG1vZHVsZUxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7Cgl9CgkKCXByaXZhdGUgdm9pZCBhZGRDaGlsZE1hcChNb2R1bGVNYXAgaGVscCwgTGlzdCBwYXJlbnRzLCBJTW9kdWxlW10gY2hpbGRyZW4pIHsKCQlpZiAoY2hpbGRyZW4gPT0gbnVsbCkKCQkJcmV0dXJuOwoJCQoJCWludCBzaXplID0gY2hpbGRyZW4ubGVuZ3RoOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCUlNb2R1bGUgbW9kdWxlID0gY2hpbGRyZW5baV07CgkJCWhlbHAucGFyZW50TGlzdC5hZGQocGFyZW50cyk7CgkJCWhlbHAubW9kdWxlTGlzdC5hZGQobW9kdWxlKTsKCQkJSU1vZHVsZVtdIGNoaWxkcmVuMiA9IChJTW9kdWxlW10pIGNoaWxkTW9kdWxlTWFwLmdldChtb2R1bGUpOwoJCQlpZiAoY2hpbGRyZW4yICE9IG51bGwpIHsKCQkJCUxpc3QgcGFyZW50czIgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCQlwYXJlbnRzMi5hZGRBbGwocGFyZW50cyk7CgkJCQlwYXJlbnRzMi5hZGQobW9kdWxlKTsKCQkJCWFkZENoaWxkTWFwKGhlbHAsIHBhcmVudHMyLCBjaGlsZHJlbjIpOwoJCQl9CgkJfQoJfQoKCXB1YmxpYyBNb2R1bGVNYXAgZ2V0TW9kdWxlTWFwKCkgewoJCWZpbmFsIE1vZHVsZU1hcCBoZWxwID0gbmV3IE1vZHVsZU1hcCgpOwoJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBkZXBsb3llZC5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSU1vZHVsZSBtb2R1bGUgPSAoSU1vZHVsZSkgaXRlcmF0b3IubmV4dCgpOwoJCQloZWxwLnBhcmVudExpc3QuYWRkKG51bGwpOwoJCQloZWxwLm1vZHVsZUxpc3QuYWRkKG1vZHVsZSk7CgkJCUlNb2R1bGVbXSBjaGlsZHJlbiA9IChJTW9kdWxlW10pIGNoaWxkTW9kdWxlTWFwLmdldChtb2R1bGUpOwoJCQlpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewoJCQkJTGlzdCBwYXJlbnRzID0gbmV3IEFycmF5TGlzdCgpOwoJCQkJcGFyZW50cy5hZGQobW9kdWxlKTsKCQkJCWFkZENoaWxkTWFwKGhlbHAsIHBhcmVudHMsIGNoaWxkcmVuKTsKCQkJfQoJCX0KCQkKCQlyZXR1cm4gaGVscDsKCX0KfQ==