LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBHb3JrZW0gRXJjYW4gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE5hY2kgTS4gRGFpCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBFVEVSQVRJT04gQS5TLiBPUgogKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgogKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAogKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQogKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4gIEZvciBtb3JlCiAqIGluZm9ybWF0aW9uIG9uIGV0ZXJhdGlvbiwgcGxlYXNlIHNlZQogKiA8aHR0cDovL3d3dy5ldGVyYXRpb24uY29tLz4uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmNvcmUuaW50ZXJuYWw7CgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JVk1JbnN0YWxsOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5JVk1JbnN0YWxsVHlwZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSmF2YVJ1bnRpbWU7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuc2VydmVydHlwZS5kZWZpbml0aW9uLkFyY2hpdmVUeXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLnNlcnZlcnR5cGUuZGVmaW5pdGlvbi5DbGFzc3BhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuc2VydmVydHlwZS5kZWZpbml0aW9uLlNlcnZlclJ1bnRpbWU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuUnVudGltZURlbGVnYXRlOwovKioKICogR2VuZXJpYyBzZXJ2ZXIgcnVudGltZSBzdXBwb3J0LgogKgogKiBAYXV0aG9yIEdvcmtlbSBFcmNhbgogKi8KcHVibGljIGNsYXNzIEdlbmVyaWNTZXJ2ZXJSdW50aW1lIGV4dGVuZHMgUnVudGltZURlbGVnYXRlIAp7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPUF9WTV9JTlNUQUxMX1RZUEVfSUQgPSAidm0taW5zdGFsbC10eXBlLWlkIjsKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QX1ZNX0lOU1RBTExfSUQgPSAidm0taW5zdGFsbC1pZCI7CglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWRVJfREVGSU5JVElPTl9JRCA9ICJzZXJ2ZXJfZGVmaW5pdGlvbl9pZCI7CglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTRVJWRVJfSU5TVEFOQ0VfUFJPUEVSVElFUyA9ICJnZW5lcmljX3NlcnZlcl9pbnN0YW5jZV9wcm9wZXJ0aWVzIjsKCgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuY29yZS5JR2VuZXJpY1J1bnRpbWUjZ2V0Vk1JbnN0YWxsVHlwZUlkKCkKCSAqLwoJcHVibGljIFN0cmluZyBnZXRWTUluc3RhbGxUeXBlSWQoKSB7CgkJcmV0dXJuIGdldEF0dHJpYnV0ZShQUk9QX1ZNX0lOU1RBTExfVFlQRV9JRCwgKFN0cmluZyludWxsKTsKCX0KCQoJcHVibGljIGJvb2xlYW4gaXNVc2luZ0RlZmF1bHRKUkUoKSB7CgkJcmV0dXJuIGdldFZNSW5zdGFsbFR5cGVJZCgpID09IG51bGw7Cgl9CgoJLyogKG5vbi1KYXZhZG9jKQoJICogQHNlZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmNvcmUuSUdlbmVyaWNSdW50aW1lI2dldFZNSW5zdGFsbElkKCkKCSAqLwoJcHVibGljIFN0cmluZyBnZXRWTUluc3RhbGxJZCgpIHsKCQlyZXR1cm4gZ2V0QXR0cmlidXRlKFBST1BfVk1fSU5TVEFMTF9JRCwgKFN0cmluZyludWxsKTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuY29yZS5JR2VuZXJpY1J1bnRpbWUjZ2V0Vk1JbnN0YWxsKCkKCSAqLwoJcHVibGljIElWTUluc3RhbGwgZ2V0Vk1JbnN0YWxsKCkgewoJCWlmIChnZXRWTUluc3RhbGxUeXBlSWQoKSA9PSBudWxsKQoJCQlyZXR1cm4gSmF2YVJ1bnRpbWUuZ2V0RGVmYXVsdFZNSW5zdGFsbCgpOwoJCXRyeSB7CgkJCUlWTUluc3RhbGxUeXBlIHZtSW5zdGFsbFR5cGUgPSBKYXZhUnVudGltZS5nZXRWTUluc3RhbGxUeXBlKGdldFZNSW5zdGFsbFR5cGVJZCgpKTsKCQkJSVZNSW5zdGFsbFtdIHZtSW5zdGFsbHMgPSB2bUluc3RhbGxUeXBlLmdldFZNSW5zdGFsbHMoKTsKCQkJaW50IHNpemUgPSB2bUluc3RhbGxzLmxlbmd0aDsKCQkJU3RyaW5nIGlkID0gZ2V0Vk1JbnN0YWxsSWQoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCWlmIChpZC5lcXVhbHModm1JbnN0YWxsc1tpXS5nZXRJZCgpKSkKCQkJCQlyZXR1cm4gdm1JbnN0YWxsc1tpXTsKCQkJfQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQlyZXR1cm4gbnVsbDsKCQoJfQoKCS8qIChub24tSmF2YWRvYykKCSAqIEBzZWUgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5jb3JlLklHZW5lcmljUnVudGltZSN2YWxpZGF0ZSgpCgkgKi8KCXB1YmxpYyBJU3RhdHVzIHZhbGlkYXRlKCkgewoJCWlmIChnZXRWTUluc3RhbGwoKSA9PSBudWxsKSB7CgkJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIENvcmVQbHVnaW4uUExVR0lOX0lELCAwLCBHZW5lcmljU2VydmVyQ29yZU1lc3NhZ2VzLmVycm9ySlJFLCBudWxsKTsKCQl9CgkJU2VydmVyUnVudGltZSBzZXJ2ZXJUeXBlRGVmaW5pdGlvbiA9IGdldFNlcnZlclR5cGVEZWZpbml0aW9uKCk7CiAgICAgICAgaWYoc2VydmVyVHlwZURlZmluaXRpb24gPT0gbnVsbCkgewoJCSAgICByZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCwgR2VuZXJpY1NlcnZlckNvcmVNZXNzYWdlcy5lcnJvck5vU2VydmVyVHlwZSwgbnVsbCk7CiAgICAgICAgfQoJCWlmKHNlcnZlclR5cGVEZWZpbml0aW9uLmdldENsYXNzcGF0aCgpPT0gbnVsbCB8fCBzZXJ2ZXJUeXBlRGVmaW5pdGlvbi5nZXRDbGFzc3BhdGgoKS5zaXplKCk8MSkgewogICAgICAgICAgICByZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBDb3JlUGx1Z2luLlBMVUdJTl9JRCwgMCAsR2VuZXJpY1NlcnZlckNvcmVNZXNzYWdlcy5lcnJvck5vQ2xhc3NwYXRoLG51bGwpOwoJCX0KICAgICAgICByZXR1cm4gdmFsaWRhdGVDbGFzc3BhdGhzKHNlcnZlclR5cGVEZWZpbml0aW9uKTsKCX0KCgkvKioKCSAqIENoZWNrcyBhbGwgZGVmaW5lZCBjbGFzc3BhdGhzLgoJICovCglwcm90ZWN0ZWQgSVN0YXR1cyB2YWxpZGF0ZUNsYXNzcGF0aHMoU2VydmVyUnVudGltZSBzZXJ2ZXJUeXBlRGVmaW5pdGlvbikgewoJCUl0ZXJhdG9yIGNwTGlzdCAgPSBzZXJ2ZXJUeXBlRGVmaW5pdGlvbi5nZXRDbGFzc3BhdGgoKS5pdGVyYXRvcigpOwogICAgICAgIHdoaWxlIChjcExpc3QuaGFzTmV4dCgpKSB7CgkJCUNsYXNzcGF0aCBjcHRoID0gKENsYXNzcGF0aCkgY3BMaXN0Lm5leHQoKTsKCSAgICAgICAgaWYoY3B0aC5nZXRBcmNoaXZlKCk9PSBudWxsIHx8IGNwdGguZ2V0QXJjaGl2ZSgpLnNpemUoKTwxKQoJICAgICAgICAgICAgcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgQ29yZVBsdWdpbi5QTFVHSU5fSUQsIDAgLEdlbmVyaWNTZXJ2ZXJDb3JlTWVzc2FnZXMuZXJyb3JOb0NsYXNzcGF0aCxudWxsKTsKCQkJSXRlcmF0b3IgYXJjaEl0ZXIgPSBjcHRoLmdldEFyY2hpdmUoKS5pdGVyYXRvcigpOwoJCQl3aGlsZSAoYXJjaEl0ZXIuaGFzTmV4dCgpKSB7CgkJCQlBcmNoaXZlVHlwZSBhcmNoID0gKEFyY2hpdmVUeXBlKSBhcmNoSXRlci5uZXh0KCk7CgkJCQlTdHJpbmcgYXJjUGF0aCA9IHNlcnZlclR5cGVEZWZpbml0aW9uLmdldFJlc29sdmVyKCkucmVzb2x2ZVByb3BlcnRpZXMoYXJjaC5nZXRQYXRoKCkpOwoJCSAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoYXJjUGF0aCk7CgkJICAgICAgICAgICAgaWYoZi5leGlzdHMoKT09ZmFsc2UpCgkJICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIENvcmVQbHVnaW4uUExVR0lOX0lELCAwICxHZW5lcmljU2VydmVyQ29yZU1lc3NhZ2VzLmJpbmQoR2VuZXJpY1NlcnZlckNvcmVNZXNzYWdlcy5lcnJvck1pc3NpbmdDbGFzc3BhdGhFbnRyeSxmLmdldFBhdGgoKSksbnVsbCk7CQoJCQl9CgkJfQogICAgICAgIHJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIENvcmVQbHVnaW4uUExVR0lOX0lELCAwLCAiIiwgbnVsbCk7Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgU2VydmVyVHlwZURlZmluaXRpb24gZm9yIHRoaXMgcnVudGltZS4gCgkgKiBQb3B1bGF0ZWQgd2l0aCB0aGUgdXNlciBwcm9wZXJ0aWVzIGlmIGV4aXN0cy4gCgkgKiAKCSAqIEByZXR1cm4gcG9wdWxhdGVkIFNlcnZlclR5cGVEZWZpbml0aW9uCgkgKi8KCXB1YmxpYyBTZXJ2ZXJSdW50aW1lIGdldFNlcnZlclR5cGVEZWZpbml0aW9uKCkKCXsKCSAgIFN0cmluZyBpZD0gIGdldFJ1bnRpbWUoKS5nZXRSdW50aW1lVHlwZSgpLmdldElkKCk7CgkgICBNYXAgcHJvcGVydGllcyA9IGdldEF0dHJpYnV0ZShTRVJWRVJfSU5TVEFOQ0VfUFJPUEVSVElFUywoTWFwKW51bGwpOwoJICAgaWYoaWQ9PW51bGwpCgkgICAgICAgcmV0dXJuIG51bGw7CgkgICByZXR1cm4gQ29yZVBsdWdpbi5nZXREZWZhdWx0KCkuZ2V0U2VydmVyVHlwZURlZmluaXRpb25NYW5hZ2VyKCkuZ2V0U2VydmVyUnVudGltZURlZmluaXRpb24oaWQscHJvcGVydGllcyk7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFZNSW5zdGFsbChJVk1JbnN0YWxsIHZtSW5zdGFsbCkgewoJCWlmICh2bUluc3RhbGwgPT0gbnVsbCkgewoJCQlzZXRWTUluc3RhbGwobnVsbCwgbnVsbCk7CgkJfSBlbHNlCgkJCXNldFZNSW5zdGFsbCh2bUluc3RhbGwuZ2V0Vk1JbnN0YWxsVHlwZSgpLmdldElkKCksIHZtSW5zdGFsbC5nZXRJZCgpKTsKCX0KCQoJcHJpdmF0ZSB2b2lkIHNldFZNSW5zdGFsbChTdHJpbmcgdHlwZUlkLCBTdHJpbmcgaWQpIHsKCQlpZiAodHlwZUlkID09IG51bGwpCgkJCXNldEF0dHJpYnV0ZShQUk9QX1ZNX0lOU1RBTExfVFlQRV9JRCwgKFN0cmluZyludWxsKTsKCQllbHNlCgkJCXNldEF0dHJpYnV0ZShQUk9QX1ZNX0lOU1RBTExfVFlQRV9JRCwgdHlwZUlkKTsKCQkKCQlpZiAoaWQgPT0gbnVsbCkKCQkJc2V0QXR0cmlidXRlKFBST1BfVk1fSU5TVEFMTF9JRCwgKFN0cmluZyludWxsKTsKCQllbHNlCgkJCXNldEF0dHJpYnV0ZShQUk9QX1ZNX0lOU1RBTExfSUQsIGlkKTsKCX0KCQoJCglwdWJsaWMgTWFwIGdldFNlcnZlckluc3RhbmNlUHJvcGVydGllcygpIHsKCQlyZXR1cm4gZ2V0QXR0cmlidXRlKFNFUlZFUl9JTlNUQU5DRV9QUk9QRVJUSUVTLCBuZXcgSGFzaE1hcCgpKTsKCX0KCQoJcHVibGljIFN0cmluZyBnZXRTZXJ2ZXJEZWZpbml0aW9uSWQoKSB7CgkJcmV0dXJuIGdldEF0dHJpYnV0ZShTRVJWRVJfREVGSU5JVElPTl9JRCwgKFN0cmluZykgbnVsbCk7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFNlcnZlckluc3RhbmNlUHJvcGVydGllcyhNYXAgbWFwKSB7CgkJc2V0QXR0cmlidXRlKFNFUlZFUl9JTlNUQU5DRV9QUk9QRVJUSUVTLCBtYXApOwoJfQoJCglwdWJsaWMgdm9pZCBzZXRTZXJ2ZXJEZWZpbml0aW9uSWQoU3RyaW5nIHMpIHsKCQlzZXRBdHRyaWJ1dGUoU0VSVkVSX0RFRklOSVRJT05fSUQsIHMpOwoJfQoJCn0=