LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA3LCAyMDA5IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqICAgICBJQk0gQ29ycG9yYXRpb24gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIFdpbmRSaXZlciAtIGh0dHBzOi8vYnVncy5lY2xpcHNlLm9yZy9idWdzL3Nob3dfYnVnLmNnaT9pZD0yMjczNzIKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5wMi5lbmdpbmU7CgppbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5wcm92aXNpb25hbC5wMi5yZXBvc2l0b3J5LklSZXBvc2l0b3J5TWFuYWdlcjsKCmltcG9ydCBqYXZhLm5ldC5VUkk7CmltcG9ydCBqYXZhLnV0aWwuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS4qOwppbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5wMi5jb3JlLmhlbHBlcnMuU2VydmljZUhlbHBlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwucHJvdmlzaW9uYWwucDIuYXJ0aWZhY3QucmVwb3NpdG9yeS4qOwppbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5wcm92aXNpb25hbC5wMi5jb3JlLlByb3Zpc2lvbkV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwucHJvdmlzaW9uYWwucDIuZW5naW5lLlByb3Zpc2lvbmluZ0NvbnRleHQ7CgpwdWJsaWMgY2xhc3MgRG93bmxvYWRNYW5hZ2VyIHsKCXByaXZhdGUgUHJvdmlzaW9uaW5nQ29udGV4dCBwcm92Q29udGV4dCA9IG51bGw7CglBcnJheUxpc3QgcmVxdWVzdHNUb1Byb2Nlc3MgPSBuZXcgQXJyYXlMaXN0KCk7CgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfUFJPVE9DT0wgPSAiZmlsZSI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIFRoaXMgQ29tcGFyYXRvciBzb3J0cyB0aGUgcmVwb3NpdG9yaWVzIHN1Y2ggdGhhdCC0bG9jYWy0IHJlcG9zaXRvcmllcyBhcmUgZmlyc3QKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29tcGFyYXRvciBMT0NBTF9GSVJTVF9DT01QQVJBVE9SID0gbmV3IENvbXBhcmF0b3IoKSB7CgoJCXB1YmxpYyBpbnQgY29tcGFyZShPYmplY3QgYXJnMCwgT2JqZWN0IGFyZzEpIHsKCQkJQXNzZXJ0LmlzVHJ1ZShhcmcwIGluc3RhbmNlb2YgVVJJKTsKCQkJQXNzZXJ0LmlzVHJ1ZShhcmcxIGluc3RhbmNlb2YgVVJJKTsKCgkJCVN0cmluZyBwcm90b2NvbDAgPSAoKFVSSSkgYXJnMCkuZ2V0U2NoZW1lKCk7CgkJCVN0cmluZyBwcm90b2NvbDEgPSAoKFVSSSkgYXJnMSkuZ2V0U2NoZW1lKCk7CgoJCQlpZiAoRklMRV9QUk9UT0NPTC5lcXVhbHMocHJvdG9jb2wwKSAmJiAhRklMRV9QUk9UT0NPTC5lcXVhbHMocHJvdG9jb2wxKSkKCQkJCXJldHVybiAtMTsKCQkJaWYgKCFGSUxFX1BST1RPQ09MLmVxdWFscyhwcm90b2NvbDApICYmIEZJTEVfUFJPVE9DT0wuZXF1YWxzKHByb3RvY29sMSkpCgkJCQlyZXR1cm4gMTsKCQkJcmV0dXJuIDA7CgkJfQoJfTsKCglwdWJsaWMgRG93bmxvYWRNYW5hZ2VyKFByb3Zpc2lvbmluZ0NvbnRleHQgY29udGV4dCkgewoJCXByb3ZDb250ZXh0ID0gY29udGV4dDsKCX0KCgkvKgoJICogQWRkIHRoZSBnaXZlbiBhcnRpZmFjdCB0byB0aGUgZG93bmxvYWQgcXVldWUuIFdoZW4gaXQKCSAqIGlzIGRvd25sb2FkZWQsIHB1dCBpdCBpbiB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uLgoJICovCglwdWJsaWMgdm9pZCBhZGQoSUFydGlmYWN0UmVxdWVzdCB0b0FkZCkgewoJCUFzc2VydC5pc05vdE51bGwodG9BZGQpOwoJCXJlcXVlc3RzVG9Qcm9jZXNzLmFkZCh0b0FkZCk7Cgl9CgoJcHVibGljIHZvaWQgYWRkKElBcnRpZmFjdFJlcXVlc3RbXSB0b0FkZCkgewoJCUFzc2VydC5pc05vdE51bGwodG9BZGQpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgdG9BZGQubGVuZ3RoOyBpKyspIHsKCQkJYWRkKHRvQWRkW2ldKTsKCQl9Cgl9CgoJcHJpdmF0ZSB2b2lkIGZpbHRlclVuZmV0Y2hlZCgpIHsKCQlmb3IgKEl0ZXJhdG9yIGl0ZXJhdG9yID0gcmVxdWVzdHNUb1Byb2Nlc3MuaXRlcmF0b3IoKTsgaXRlcmF0b3IuaGFzTmV4dCgpOykgewoJCQlJQXJ0aWZhY3RSZXF1ZXN0IHJlcXVlc3QgPSAoSUFydGlmYWN0UmVxdWVzdCkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAocmVxdWVzdC5nZXRSZXN1bHQoKSAhPSBudWxsICYmIHJlcXVlc3QuZ2V0UmVzdWx0KCkuaXNPSygpKSB7CgkJCQlpdGVyYXRvci5yZW1vdmUoKTsKCQkJfQoJCX0KCX0KCgkvKgoJICogU3RhcnQgdGhlIGRvd25sb2Fkcy4gUmV0dXJuIGEgc3RhdHVzIG1lc3NhZ2UgaW5kaWNhdGluZyBzdWNjZXNzIG9yIGZhaWx1cmUgb2YgdGhlIG92ZXJhbGwgb3BlcmF0aW9uCgkgKi8KCXB1YmxpYyBJU3RhdHVzIHN0YXJ0KElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCVN1Yk1vbml0b3Igc3ViTW9uaXRvciA9IFN1Yk1vbml0b3IuY29udmVydChtb25pdG9yLCBNZXNzYWdlcy5kb3dubG9hZF9hcnRpZmFjdCwgcmVxdWVzdHNUb1Byb2Nlc3Muc2l6ZSgpKTsKCQl0cnkgewoJCQlpZiAocmVxdWVzdHNUb1Byb2Nlc3MuaXNFbXB0eSgpKQoJCQkJcmV0dXJuIFN0YXR1cy5PS19TVEFUVVM7CgoJCQlJQXJ0aWZhY3RSZXBvc2l0b3J5TWFuYWdlciByZXBvTWdyID0gKElBcnRpZmFjdFJlcG9zaXRvcnlNYW5hZ2VyKSBTZXJ2aWNlSGVscGVyLmdldFNlcnZpY2UoRW5naW5lQWN0aXZhdG9yLmdldENvbnRleHQoKSwgSUFydGlmYWN0UmVwb3NpdG9yeU1hbmFnZXIuY2xhc3MuZ2V0TmFtZSgpKTsKCQkJVVJJW10gcmVwb3NpdG9yaWVzID0gbnVsbDsKCQkJaWYgKHByb3ZDb250ZXh0ID09IG51bGwgfHwgcHJvdkNvbnRleHQuZ2V0QXJ0aWZhY3RSZXBvc2l0b3JpZXMoKSA9PSBudWxsKQoJCQkJcmVwb3NpdG9yaWVzID0gcmVwb01nci5nZXRLbm93blJlcG9zaXRvcmllcyhJUmVwb3NpdG9yeU1hbmFnZXIuUkVQT1NJVE9SSUVTX0FMTCk7CgkJCWVsc2UKCQkJCXJlcG9zaXRvcmllcyA9IHByb3ZDb250ZXh0LmdldEFydGlmYWN0UmVwb3NpdG9yaWVzKCk7CgkJCWlmIChyZXBvc2l0b3JpZXMubGVuZ3RoID09IDApCgkJCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBFbmdpbmVBY3RpdmF0b3IuSUQsIE1lc3NhZ2VzLmRvd25sb2FkX25vX3JlcG9zaXRvcnksIG5ldyBFeGNlcHRpb24oKSk7CgkJCUFycmF5cy5zb3J0KHJlcG9zaXRvcmllcywgTE9DQUxfRklSU1RfQ09NUEFSQVRPUik7CgkJCWZldGNoKHJlcG9NZ3IsIHJlcG9zaXRvcmllcywgc3ViTW9uaXRvcik7CgkJCXJldHVybiBvdmVyYWxsU3RhdHVzKG1vbml0b3IpOwoJCX0gZmluYWxseSB7CgkJCXN1Yk1vbml0b3IuZG9uZSgpOwoJCX0KCX0KCglwcml2YXRlIHZvaWQgZmV0Y2goSUFydGlmYWN0UmVwb3NpdG9yeU1hbmFnZXIgcmVwb01nciwgVVJJW10gcmVwb3NpdG9yaWVzLCBTdWJNb25pdG9yIG1vbml0b3IpIHsKCQlmb3IgKGludCBpID0gMDsgaSA8IHJlcG9zaXRvcmllcy5sZW5ndGggJiYgIXJlcXVlc3RzVG9Qcm9jZXNzLmlzRW1wdHkoKSAmJiAhbW9uaXRvci5pc0NhbmNlbGVkKCk7IGkrKykgewoJCQl0cnkgewoJCQkJSUFydGlmYWN0UmVwb3NpdG9yeSBjdXJyZW50ID0gcmVwb01nci5sb2FkUmVwb3NpdG9yeShyZXBvc2l0b3JpZXNbaV0sIG1vbml0b3IubmV3Q2hpbGQoMCkpOwoJCQkJSUFydGlmYWN0UmVxdWVzdFtdIHJlcXVlc3RzID0gZ2V0UmVxdWVzdHNGb3JSZXBvc2l0b3J5KGN1cnJlbnQpOwoJCQkJSVN0YXR1cyBkbFN0YXR1cyA9IGN1cnJlbnQuZ2V0QXJ0aWZhY3RzKHJlcXVlc3RzLCBtb25pdG9yLm5ld0NoaWxkKHJlcXVlc3RzLmxlbmd0aCkpOwoJCQkJaWYgKGRsU3RhdHVzLmdldFNldmVyaXR5KCkgPT0gSVN0YXR1cy5DQU5DRUwpCgkJCQkJcmV0dXJuOwoJCQkJZmlsdGVyVW5mZXRjaGVkKCk7CgkJCQltb25pdG9yLnNldFdvcmtSZW1haW5pbmcocmVxdWVzdHNUb1Byb2Nlc3Muc2l6ZSgpKTsKCQkJfSBjYXRjaCAoUHJvdmlzaW9uRXhjZXB0aW9uIGUpIHsKCQkJCS8vc2tpcCB1bnJlYWNoYWJsZSByZXBvc2l0b3JpZXMKCQkJfQoJCX0KCX0KCglwcml2YXRlIElBcnRpZmFjdFJlcXVlc3RbXSBnZXRSZXF1ZXN0c0ZvclJlcG9zaXRvcnkoSUFydGlmYWN0UmVwb3NpdG9yeSByZXBvc2l0b3J5KSB7CgkJQXJyYXlMaXN0IGFwcGxpY2FibGUgPSBuZXcgQXJyYXlMaXN0KCk7CgkJZm9yIChJdGVyYXRvciBpdCA9IHJlcXVlc3RzVG9Qcm9jZXNzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKCQkJSUFydGlmYWN0UmVxdWVzdCByZXF1ZXN0ID0gKElBcnRpZmFjdFJlcXVlc3QpIGl0Lm5leHQoKTsKCQkJaWYgKHJlcG9zaXRvcnkuY29udGFpbnMocmVxdWVzdC5nZXRBcnRpZmFjdEtleSgpKSkKCQkJCWFwcGxpY2FibGUuYWRkKHJlcXVlc3QpOwoJCX0KCQlyZXR1cm4gKElBcnRpZmFjdFJlcXVlc3RbXSkgYXBwbGljYWJsZS50b0FycmF5KG5ldyBJQXJ0aWZhY3RSZXF1ZXN0W2FwcGxpY2FibGUuc2l6ZSgpXSk7Cgl9CgoJLy8JcHJpdmF0ZSB2b2lkIG5vdGlmeUZldGNoZWQoKSB7CgkvLwkJUHJvdmlzaW9uaW5nRXZlbnRCdXMgYnVzID0gKFByb3Zpc2lvbmluZ0V2ZW50QnVzKSBTZXJ2aWNlSGVscGVyLmdldFNlcnZpY2UoRG93bmxvYWRBY3RpdmF0b3IuY29udGV4dCwgUHJvdmlzaW9uaW5nRXZlbnRCdXMuY2xhc3MpOwoJLy8JCWJ1cy5wdWJsaXNoRXZlbnQoKTsKCS8vCX0KCglwcml2YXRlIElTdGF0dXMgb3ZlcmFsbFN0YXR1cyhJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlpZiAobW9uaXRvciAhPSBudWxsICYmIG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQlyZXR1cm4gU3RhdHVzLkNBTkNFTF9TVEFUVVM7CgoJCWlmIChyZXF1ZXN0c1RvUHJvY2Vzcy5zaXplKCkgPT0gMCkKCQkJcmV0dXJuIFN0YXR1cy5PS19TVEFUVVM7CgoJCU11bHRpU3RhdHVzIHJlc3VsdCA9IG5ldyBNdWx0aVN0YXR1cyhFbmdpbmVBY3RpdmF0b3IuSUQsIElTdGF0dXMuT0ssIG51bGwsIG51bGwpOwoJCWZvciAoSXRlcmF0b3IgaXRlcmF0b3IgPSByZXF1ZXN0c1RvUHJvY2Vzcy5pdGVyYXRvcigpOyBpdGVyYXRvci5oYXNOZXh0KCk7KSB7CgkJCUlTdGF0dXMgZmFpbGVkID0gKChJQXJ0aWZhY3RSZXF1ZXN0KSBpdGVyYXRvci5uZXh0KCkpLmdldFJlc3VsdCgpOwoJCQlpZiAoZmFpbGVkICE9IG51bGwgJiYgIWZhaWxlZC5pc09LKCkpCgkJCQlyZXN1bHQuYWRkKGZhaWxlZCk7CgkJfQoJCXJldHVybiByZXN1bHQ7Cgl9Cn0K