LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS51dGlsOwoKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKCmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSU1vZHVsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5Nb2R1bGVGaWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLk1vZHVsZUZvbGRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC4qOwovKioKICogQSBzaW1wbGUgSU1vZHVsZVByb2plY3QgdGhhdCBtYXBzIGEgZm9sZGVyIHdpdGhpbiBhIHByb2plY3QKICogKG9yIHRoZSByb290IG9mIHRoZSBwcm9qZWN0IGl0c2VsZikgdG8gdGhlIG1vZHVsZS4KICogCiAqIEBzaW5jZSAxLjAKICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBQcm9qZWN0TW9kdWxlIGV4dGVuZHMgTW9kdWxlRGVsZWdhdGUgewoJcHJvdGVjdGVkIElQcm9qZWN0IHByb2plY3Q7Cglwcm90ZWN0ZWQgSVBhdGggcm9vdDsKCgkvKioKCSAqIENyZWF0ZSBhIG5ldyBwcm9qZWN0IG1vZHVsZS4KCSAqLwoJcHVibGljIFByb2plY3RNb2R1bGUoKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogQ3JlYXRlIGEgbmV3IHByb2plY3QgbW9kdWxlIGluIHRoZSBnaXZlbiBwcm9qZWN0LgoJICogCgkgKiBAcGFyYW0gcHJvamVjdCB0aGUgcHJvamVjdCBjb250YWluaW5nIHRoZSBtb2R1bGUKCSAqLwoJcHVibGljIFByb2plY3RNb2R1bGUoSVByb2plY3QgcHJvamVjdCkgewoJCXRoaXMucHJvamVjdCA9IHByb2plY3Q7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBwcm9qZWN0IHRoYXQgdGhlIG1vZHVsZSBpcyBjb250YWluZWQgaW4uCgkgKiAKCSAqIEByZXR1cm4gdGhlIHByb2plY3QgdGhhdCB0aGUgbW9kdWxlIGlzIGNvbnRhaW5lZCBpbgoJICovCglwdWJsaWMgSVByb2plY3QgZ2V0UHJvamVjdCgpIHsKCQlyZXR1cm4gcHJvamVjdDsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHJvb3QgZm9sZGVyLiBUaGUgcm9vdCBmb2xkZXIgaXMgdGhlIHByb2plY3QgcmVsYXRpdmUgcGF0aAoJICogdGhhdCBwb2ludHMgdG8gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoZSBtb2R1bGUuIEFsbCByZXNvdXJjZXMgY29udGFpbmVkCgkgKiB3aXRoaW4gdGhpcyBmb2xkZXIgYmVsb25nIHRvIHRoZSBtb2R1bGUuCgkgKiAKCSAqIEByZXR1cm4gdGhlIHJvb3QgcHJvamVjdC1yZWxhdGl2ZSBmb2xkZXIgdGhhdCBjb250YWlucyB0aGUgY29udGVudHMKCSAqICAgIG9mIHRoZSBtb2R1bGUKCSAqLwoJcHVibGljIElQYXRoIGdldFJvb3RGb2xkZXIoKSB7CgkJcmV0dXJuIHJvb3Q7Cgl9CgoJLyoKCSAqIEBzZWUgSU1vZHVsZVByb2plY3QjZ2V0TW9kdWxlUmVzb3VyY2VEZWx0YShJUmVzb3VyY2VEZWx0YSkKCSAqLwoJLypwdWJsaWMgSU1vZHVsZVJlc291cmNlRGVsdGEgZ2V0TW9kdWxlUmVzb3VyY2VEZWx0YShJUmVzb3VyY2VEZWx0YSBkZWx0YSkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIj4gZ2V0TW9kdWxlUmVzb3VyY2VEZWx0YSIpOwoJCUlQYXRoIHJvb3QyID0gbnVsbDsKCQl0cnkgewoJCQlyb290MiA9IGdldFJvb3RGb2xkZXIoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJFcnJvciBnZXR0aW5nIHJvb3QyIik7CgkJfQoJCWlmIChyb290MiA9PSBudWxsKSB7CgkJCXJldHVybiBjb252ZXJ0Q2hpbGRyZW4oZGVsdGEsIG51bGwpOwoJCX0KCQljbGFzcyBIZWxwZXIgewoJCQlib29sZWFuIGZvdW5kID0gZmFsc2U7CgkJCUlNb2R1bGVSZXNvdXJjZURlbHRhIGRlbHRhMjsKCQl9CgkJZmluYWwgSGVscGVyIGhlbHBlciA9IG5ldyBIZWxwZXIoKTsKCQlmaW5hbCBJUGF0aCByb290MyA9IHJvb3QyOwoJCXRyeSB7CgkJCWRlbHRhLmFjY2VwdChuZXcgSVJlc291cmNlRGVsdGFWaXNpdG9yKCkgewoJCQkJcHVibGljIGJvb2xlYW4gdmlzaXQoSVJlc291cmNlRGVsdGEgdmlzaXREZWx0YSkgewoJCQkJCWlmICghaGVscGVyLmZvdW5kICYmIHJvb3QzLmVxdWFscyh2aXNpdERlbHRhLmdldFByb2plY3RSZWxhdGl2ZVBhdGgoKSkpIHsKCQkJCQkJaGVscGVyLmRlbHRhMiA9IGNvbnZlcnRDaGlsZHJlbih2aXNpdERlbHRhLCBudWxsKTsKCQkJCQkJaGVscGVyLmZvdW5kID0gdHJ1ZTsKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCX0KCQkJfSk7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIjwgZ2V0TW9kdWxlUmVzb3VyY2VEZWx0YSIpOwoJCQlyZXR1cm4gaGVscGVyLmRlbHRhMjsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3QgZ2V0IG1vZHVsZSByZXNvdXJjZSBkZWx0YSIpOwoJCX0KCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICI8IGdldE1vZHVsZVJlc291cmNlRGVsdGEgbnVsbCIpOwoJCXJldHVybiBudWxsOwoJfSovCgkKCS8qKgoJICogCgkgKi8KCS8qcHJvdGVjdGVkIElNb2R1bGVSZXNvdXJjZURlbHRhIGNvbnZlcnRDaGlsZHJlbihJUmVzb3VyY2VEZWx0YSBkZWx0YSwgSU1vZHVsZUZvbGRlciBwYXJlbnQpIHsKCQlpbnQgZmxhZ3MgPSBkZWx0YS5nZXRLaW5kKCk7CgkJaW50IGtpbmQgPSBJTW9kdWxlUmVzb3VyY2VEZWx0YS5OT19DSEFOR0U7CgkJaWYgKGZsYWdzID09IElSZXNvdXJjZURlbHRhLkFEREVEKQoJCQlraW5kID0gSU1vZHVsZVJlc291cmNlRGVsdGEuQURERUQ7CgkJZWxzZSBpZiAoZmxhZ3MgPT0gSVJlc291cmNlRGVsdGEuUkVNT1ZFRCkKCQkJa2luZCA9IElNb2R1bGVSZXNvdXJjZURlbHRhLlJFTU9WRUQ7CgkJZWxzZSBpZiAoZmxhZ3MgPT0gSVJlc291cmNlRGVsdGEuQ0hBTkdFRCkKCQkJa2luZCA9IElNb2R1bGVSZXNvdXJjZURlbHRhLkNIQU5HRUQ7CgkJCgkJSVJlc291cmNlIHJlc291cmNlID0gZGVsdGEuZ2V0UmVzb3VyY2UoKTsKCQkKCQlJTW9kdWxlUmVzb3VyY2UgcHViUmVzb3VyY2UgPSBudWxsOwoJCWlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIElDb250YWluZXIpCgkJCXB1YlJlc291cmNlID0gbmV3IFByb2plY3RNb2R1bGVGb2xkZXIodGhpcywgcGFyZW50LCAoSUNvbnRhaW5lcikgcmVzb3VyY2UpOwkKCQllbHNlIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIElGaWxlKSB7CgkJCWlmIChkZWx0YS5nZXRGbGFncygpID09IElSZXNvdXJjZURlbHRhLk1BUktFUlMpCgkJCQlyZXR1cm4gbnVsbDsKCQkJcHViUmVzb3VyY2UgPSBuZXcgUHJvamVjdE1vZHVsZUZpbGUodGhpcywgcGFyZW50LCAoSUZpbGUpIHJlc291cmNlKTsKCQl9CgkJCgkJTW9kdWxlUmVzb3VyY2VEZWx0YSBkZXBsb3lEZWx0YSA9IG5ldyBNb2R1bGVSZXNvdXJjZURlbHRhKHB1YlJlc291cmNlLCBraW5kKTsKCQkKCQlJUmVzb3VyY2VEZWx0YVtdIGNoaWxkcmVuID0gZGVsdGEuZ2V0QWZmZWN0ZWRDaGlsZHJlbigpOwoJCWlmIChjaGlsZHJlbiAhPSBudWxsICYmIHB1YlJlc291cmNlIGluc3RhbmNlb2YgSU1vZHVsZUZvbGRlcikgewoJCQlpbnQgc2l6ZSA9IGNoaWxkcmVuLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlNb2R1bGVSZXNvdXJjZURlbHRhIGNoaWxkRGVsdGEgPSBjb252ZXJ0Q2hpbGRyZW4oY2hpbGRyZW5baV0sIChJTW9kdWxlRm9sZGVyKSBwdWJSZXNvdXJjZSk7CgkJCQlpZiAoY2hpbGREZWx0YSAhPSBudWxsKQoJCQkJCWRlcGxveURlbHRhLmFkZENoaWxkKGNoaWxkRGVsdGEpOwoJCQl9CgkJfQoJCXJldHVybiBkZXBsb3lEZWx0YTsKCX0qLwoKCS8qKgoJICogSGVscGVyIG1ldGhvZCAtIHJldHVybnMgdGhlIG1vZHVsZSdzIGlkLgoJICogCgkgKiBAcmV0dXJuIHRoZSBtb2R1bGUgaWQKCSAqLwoJcHVibGljIFN0cmluZyBnZXRJZCgpIHsKCQlyZXR1cm4gZ2V0UHJvamVjdCgpLmdldE5hbWUoKTsKCQkvL3JldHVybiBnZXRNb2R1bGUoKS5nZXRJZCgpOwoJfQoKCS8qKgoJICogQHNlZSBNb2R1bGVEZWxlZ2F0ZSN2YWxpZGF0ZSgpCgkgKi8KCXB1YmxpYyBJU3RhdHVzIHZhbGlkYXRlKCkgewoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogQHNlZSBNb2R1bGVEZWxlZ2F0ZSNtZW1iZXJzKCkKCSAqLwoJcHVibGljIElNb2R1bGVSZXNvdXJjZVtdIG1lbWJlcnMoKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJSVBhdGggcm9vdDIgPSBudWxsOwoJCXRyeSB7CgkJCXJvb3QyID0gZ2V0Um9vdEZvbGRlcigpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQl0cnkgewoJCQlpZiAocm9vdDIgPT0gbnVsbCB8fCByb290Mi5pc1Jvb3QoKSB8fCByb290Mi5lcXVhbHMobmV3IFBhdGgoIiIpKSB8fCByb290Mi5lcXVhbHMobmV3IFBhdGgoIi8iKSkpCgkJCQlyZXR1cm4gZ2V0TW9kdWxlUmVzb3VyY2VzKFBhdGguRU1QVFksIGdldFByb2plY3QoKSk7CgkJCQoJCQlJRm9sZGVyIGZvbGRlciA9IHByb2plY3QuZ2V0Rm9sZGVyKHJvb3QyKTsKCQkJcmV0dXJuIGdldE1vZHVsZVJlc291cmNlcyhQYXRoLkVNUFRZLCBmb2xkZXIpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgewoJCQl0aHJvdyBlOwoJCX0KCX0KCglwcm90ZWN0ZWQgSU1vZHVsZVJlc291cmNlW10gZ2V0TW9kdWxlUmVzb3VyY2VzKElQYXRoIHBhdGgsIElDb250YWluZXIgY29udGFpbmVyKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoKIAkJSVJlc291cmNlW10gcmVzb3VyY2VzID0gY29udGFpbmVyLm1lbWJlcnMoKTsKCSAJaWYgKHJlc291cmNlcyAhPSBudWxsKSB7CgkgCQlpbnQgc2l6ZSA9IHJlc291cmNlcy5sZW5ndGg7CgkgCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSVJlc291cmNlIHJlc291cmNlID0gcmVzb3VyY2VzW2ldOwoJCQkJaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSUNvbnRhaW5lcikgewoJCQkJCUlDb250YWluZXIgY29udGFpbmVyMiA9IChJQ29udGFpbmVyKSByZXNvdXJjZTsKCQkJCQlNb2R1bGVGb2xkZXIgbWYgPSBuZXcgTW9kdWxlRm9sZGVyKGNvbnRhaW5lcjIuZ2V0TmFtZSgpLCBwYXRoKTsKCQkJCQltZi5zZXRNZW1iZXJzKGdldE1vZHVsZVJlc291cmNlcyhwYXRoLmFwcGVuZChjb250YWluZXIyLmdldE5hbWUoKSksIGNvbnRhaW5lcjIpKTsKCQkJCQlsaXN0LmFkZChtZik7CgkJCQl9IGVsc2UgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSUZpbGUpIHsKCQkJCQlJRmlsZSBmaWxlID0gKElGaWxlKSByZXNvdXJjZTsKCQkJCQlsaXN0LmFkZChuZXcgTW9kdWxlRmlsZShmaWxlLmdldE5hbWUoKSwgcGF0aCwgZmlsZS5nZXRNb2RpZmljYXRpb25TdGFtcCgpKSk7CgkJCQl9CgkJCX0KCSAJfQoJIAkKCSAJSU1vZHVsZVJlc291cmNlW10gbW9kdWxlUmVzb3VyY2VzID0gbmV3IElNb2R1bGVSZXNvdXJjZVtsaXN0LnNpemUoKV07CgkgCWxpc3QudG9BcnJheShtb2R1bGVSZXNvdXJjZXMpOwoJIAlyZXR1cm4gbW9kdWxlUmVzb3VyY2VzOwoJfQoKCS8qKgoJICogSGVscGVyIG1ldGhvZCAtIHJldHVybnMgdGhlIG1vZHVsZSdzIG5hbWUuCgkgKiAKCSAqIEByZXR1cm4gdGhlIG1vZHVsZSBuYW1lCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKCQlyZXR1cm4gZ2V0UHJvamVjdCgpLmdldE5hbWUoKTsKCQkvL3JldHVybiBnZXRNb2R1bGUoKS5nZXROYW1lKCk7Cgl9CgkKCS8qKgoJICogUmV0dXJucyB0cnVlIGlmIHRoaXMgbW9kdWxlIGN1cnJlbnRseSBleGlzdHMsIGFuZCBmYWxzZSBpZiBpdCBoYXMKCSAqIGJlZW4gZGVsZXRlZCBvciBtb3ZlZCBhbmQgaXMgbm8gbG9uZ2VyIHJlcHJlc2VudGVkIGJ5IHRoaXMgbW9kdWxlLgoJICoKCSAqIEByZXR1cm4gYm9vbGVhbgoJICovCglwdWJsaWMgYm9vbGVhbiBleGlzdHMoKSB7CgkJcmV0dXJuIChnZXRQcm9qZWN0KCkgIT0gbnVsbCAmJiBnZXRQcm9qZWN0KCkuZXhpc3RzKCkpOwoJfQoJCgkvKioKCSAqIEBzZWUgT2JqZWN0I2VxdWFscyhPYmplY3QpCgkgKi8KCXB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb2JqKSB7CgkJaWYgKG9iaiA9PSBudWxsIHx8ICEob2JqIGluc3RhbmNlb2YgUHJvamVjdE1vZHVsZSkpCgkJCXJldHVybiBmYWxzZTsKCgkJUHJvamVjdE1vZHVsZSBkcCA9IChQcm9qZWN0TW9kdWxlKSBvYmo7CgkJLy9pZiAoZ2V0RmFjdG9yeUlkKCkgIT0gbnVsbCAmJiAhZ2V0RmFjdG9yeUlkKCkuZXF1YWxzKGRwLmdldEZhY3RvcnlJZCgpKSkKCQkvLwlyZXR1cm4gZmFsc2U7CgkJCQoJCUlQYXRoIHJvb3QyID0gbnVsbDsKCQl0cnkgewoJCQlyb290MiA9IGdldFJvb3RGb2xkZXIoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkvLyBpZ25vcmUKCQl9CgkJCgkJSVBhdGggcm9vdDMgPSBudWxsOwoJCXRyeSB7CgkJCXJvb3QzID0gZHAuZ2V0Um9vdEZvbGRlcigpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQkKCQlpZiAocHJvamVjdCAhPSBudWxsICYmIHByb2plY3QuZXhpc3RzKCkgJiYgIXByb2plY3QuZXF1YWxzKGRwLmdldFByb2plY3QoKSkpCgkJCXJldHVybiBmYWxzZTsKCQkKCQlpZiAoZ2V0SWQoKSAhPSBudWxsICYmICFnZXRJZCgpLmVxdWFscyhkcC5nZXRJZCgpKSkKCQkJcmV0dXJuIGZhbHNlOwoKCQlpZiAocm9vdDIgPT0gbnVsbCAmJiByb290MyAhPSBudWxsKQoJCQlyZXR1cm4gZmFsc2U7CgkJaWYgKHJvb3QyICE9IG51bGwgJiYgIXJvb3QyLmVxdWFscyhyb290MykpCgkJCXJldHVybiBmYWxzZTsKCgkJcmV0dXJuIHRydWU7Cgl9CgkKCS8qKgoJICogQ2FsbGVkIHdoZW4gdGhlIGxpc3RlbmVyIHBhdGhzIGZyb20gdGhlIG1vZHVsZSBmYWN0b3J5IGNoYW5nZS4KCSAqIFVzZSB0aGlzIG1ldGhvZCB0byByZS1jYWNoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbW9kdWxlLgoJICovCglwcm90ZWN0ZWQgdm9pZCB1cGRhdGUoKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgY2hpbGQgbW9kdWxlcyBvZiB0aGlzIG1vZHVsZS4KCSAqCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlW10KCSAqLwoJcHVibGljIElNb2R1bGVbXSBnZXRDaGlsZE1vZHVsZXMoKSB7CgkJcmV0dXJuIG51bGw7Cgl9Cn0=