LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS51dGlsOwoKaW1wb3J0IGphdmEudXRpbC4qOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuQ29yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JTW9kdWxlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLk1vZHVsZUZhY3Rvcnk7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlRyYWNlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLk1vZHVsZUZhY3RvcnlEZWxlZ2F0ZTsKLyoqCiAqIAogKiAKICogQHBsYW5uZWRmb3IgMS4wCiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSBleHRlbmRzIE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSB7Cglwcm90ZWN0ZWQgc3RhdGljIElSZXNvdXJjZUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyOwoJCglwcm90ZWN0ZWQgc3RhdGljIExpc3QgZmFjdG9yaWVzID0gbmV3IEFycmF5TGlzdCgpOwoKCXByb3RlY3RlZCBMaXN0IGFkZGVkOwoJcHJvdGVjdGVkIExpc3QgcmVtb3ZlZDsKCgkvLyBtYXAgZnJvbSBJUHJvamVjdCB0byBJTW9kdWxlW10KCXByb3RlY3RlZCBmaW5hbCBNYXAgcHJvamVjdHMgPSBuZXcgSGFzaE1hcCgpOwoJcHJvdGVjdGVkIGJvb2xlYW4gaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCgkvKioKCSAqIENvbnN0cnVjdCBhIG5ldyBQcm9qZWN0TW9kdWxlRmFjdG9yeURlbGVnYXRlLgoJICovCglwdWJsaWMgUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSgpIHsKCQlzdXBlcigpOwoJCQoJCWZhY3Rvcmllcy5hZGQodGhpcyk7CgkJCgkJLy9hZGRMaXN0ZW5lcigpOwoJfQoKCS8qKgoJICogQ2FjaGUgYW55IHByZWV4aXN0aW5nIG1vZHVsZS4KCSAqIFRPRE86IFdoZW4vd2hlcmUgaXMgdGhpcyBjYWxsZWQ/CgkgKi8KCXByb3RlY3RlZCB2b2lkIGNhY2hlTW9kdWxlcygpIHsKCQljYWNoZU1vZHVsZXModHJ1ZSk7Cgl9CgoJLyoqCgkgKiBDYWNoZSBhbnkgcHJlZXhpc3RpbmcgbW9kdWxlLgoJICogVE9ETzogV2hlbi93aGVyZSBpcyB0aGlzIGNhbGxlZD8KCSAqLwoJcHJvdGVjdGVkIHZvaWQgY2FjaGVNb2R1bGVzKGJvb2xlYW4gZm9yY2VVcGRhdGUpIHsgCgkJdHJ5IHsKCQkJSVByb2plY3RbXSBwcm9qZWN0czIgPSBnZXRXb3Jrc3BhY2VSb290KCkuZ2V0UHJvamVjdHMoKTsKCQkJaW50IHNpemUgPSBwcm9qZWN0czIubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJLy9UcmFjZS50cmFjZSgiY2FjaGluZzogIiArIHRoaXMgKyAiICIgKyBwcm9qZWN0c1tpXSArICIgIiArIGlzVmFsaWRNb2R1bGUocHJvamVjdHNbaV0pKTsKCQkJCWlmKCFwcm9qZWN0czJbaV0uaXNBY2Nlc3NpYmxlKCkpCgkJCQkJcmVtb3ZlTW9kdWxlcyhwcm9qZWN0czJbaV0pOwoJCQkJZWxzZSBpZiAoZm9yY2VVcGRhdGUgfHwgbmVlZHNVcGRhdGluZyhwcm9qZWN0czJbaV0pICYmIChpc1ZhbGlkTW9kdWxlKHByb2plY3RzMltpXSkpKSB7CgkJCQkJYWRkTW9kdWxlcyhwcm9qZWN0czJbaV0pOwoJCQkJfSAKCQkJfQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGNhY2hpbmcgbW9kdWxlcyIsIGUpOwoJCX0gZmluYWxseSB7CgkJCWluaXRpYWxpemVkID0gdHJ1ZTsKCQl9Cgl9CgoJcHJvdGVjdGVkIGJvb2xlYW4gbmVlZHNVcGRhdGluZyhJUHJvamVjdCBwcm9qZWN0KSB7CgkJcmV0dXJuIHRydWU7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIHdvcmtzcGFjZSByb290LgoJICogCgkgKiBAcmV0dXJuIHRoZSB3b3Jrc3BhY2Ugcm9vdAoJICovCglwcml2YXRlIHN0YXRpYyBJV29ya3NwYWNlUm9vdCBnZXRXb3Jrc3BhY2VSb290KCkgewoJCXJldHVybiBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgbW9kdWxlcyBmb3IgdGhlIGdpdmVuIHByb2plY3QsIG9yIG51bGwKCSAqIGlmIHRoaXMgZmFjdG9yeSBkb2VzIG5vdCBoYXZlIGEgbW9kdWxlIGZvciB0aGUgZ2l2ZW4gcHJvamVjdC4KCSAqIAoJICogQHBhcmFtIHByb2plY3QgYSBwcm9qZWN0CgkgKiBAcmV0dXJuIGFuIGFycmF5IG9mIG1vZHVsZXMuCgkgKi8KCXB1YmxpYyBJTW9kdWxlW10gZ2V0TW9kdWxlcyhJUHJvamVjdCBwcm9qZWN0KSB7CgkJdHJ5IHsKCQkJcmV0dXJuIChJTW9kdWxlW10pIHByb2plY3RzLmdldChwcm9qZWN0KTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkvLyBpZ25vcmUKCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoqCgkgKiBBZGQgYSByZXNvdXJjZSBsaXN0ZW5lciB0byB0aGUgd29ya3NwYWNlLgoJICogCgkgKiBAZGVwcmVjYXRlZAoJICovCglwcm90ZWN0ZWQgc3RhdGljIHZvaWQgYWRkTGlzdGVuZXIoKSB7CgkJLy8gZG8gbm90aGluZwoJCS8qaWYgKGxpc3RlbmVyICE9IG51bGwpCgkJCXJldHVybjsKCgkJbGlzdGVuZXIgPSBuZXcgSVJlc291cmNlQ2hhbmdlTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHJlc291cmNlQ2hhbmdlZChJUmVzb3VyY2VDaGFuZ2VFdmVudCBldmVudCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiLT4tIFByb2plY3RNb2R1bGVGYWN0b3J5RGVsZWdhdGUgbGlzdGVuZXIgcmVzcG9uZGluZyB0byByZXNvdXJjZSBjaGFuZ2U6ICIgKyBldmVudC5nZXRUeXBlKCkgKyAiIC0+LSIpOwoJCQkJdHJ5IHsKCQkJCQlJUmVzb3VyY2VEZWx0YSBkZWx0YSA9IGV2ZW50LmdldERlbHRhKCk7CgkJCQkJCgkJCQkJaWYgKCFSZXNvdXJjZU1hbmFnZXIuZGVsdGFDb250YWluc0NoYW5nZWRGaWxlcyhkZWx0YSkpCgkJCQkJCXJldHVybjsKCQkJCQkKCQkJCQlkZWx0YS5hY2NlcHQobmV3IElSZXNvdXJjZURlbHRhVmlzaXRvcigpIHsKCQkJCQkJcHVibGljIGJvb2xlYW4gdmlzaXQoSVJlc291cmNlRGVsdGEgdmlzaXRvckRlbHRhKSB7CgkJCQkJCQlJUmVzb3VyY2UgcmVzb3VyY2UgPSB2aXNpdG9yRGVsdGEuZ2V0UmVzb3VyY2UoKTsKCQkJCQkJCS8vIFRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgInJlc291cmNlOiAiICsgcmVzb3VyY2UpOwoJCQkJCQkJCgkJCQkJCQkvLyBvbmx5IHJlc3BvbmQgdG8gY2hhbmdlcyB3aXRoaW4gcHJvamVjdHMKCQkJCQkJCWlmIChyZXNvdXJjZSAhPSBudWxsICYmIHJlc291cmNlIGluc3RhbmNlb2YgSVByb2plY3QpIHsKCQkJCQkJCQlJUHJvamVjdCBwcm9qZWN0ID0gKElQcm9qZWN0KSByZXNvdXJjZTsKCQkJCQkJCQloYW5kbGVHbG9iYWxQcm9qZWN0Q2hhbmdlKHByb2plY3QsIHZpc2l0b3JEZWx0YSk7CgkJCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCQkJfSBlbHNlIGlmIChyZXNvdXJjZSAhPSBudWxsICYmIHJlc291cmNlLmdldFByb2plY3QoKSAhPSBudWxsKSB7CgkJCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCQkJfSBlbHNlCgkJCQkJCQkJcmV0dXJuIHRydWU7CgkJCQkJCX0KCQkJCQl9KTsKCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJLy9UcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciByZXNwb25kaW5nIHRvIHJlc291cmNlIGNoYW5nZSIsIGUpOwoJCQkJfQoJCQkJZmlyZUdsb2JhbEV2ZW50cygpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiLTwtIERvbmUgUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSByZXNwb25kaW5nIHRvIHJlc291cmNlIGNoYW5nZSAtPC0iKTsKCQkJfQoJCX07CgkJCgkJUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmFkZFJlc291cmNlQ2hhbmdlTGlzdGVuZXIobGlzdGVuZXIsIElSZXNvdXJjZUNoYW5nZUV2ZW50LlBPU1RfQ0hBTkdFKTsqLwoJfQoKCS8qKgoJICogSGFuZGxlIGNoYW5nZXMgdG8gYSBwcm9qZWN0LgoJICogCgkgKiBAcGFyYW0gcHJvamVjdCBhIHByb2plY3QKCSAqIEBwYXJhbSBkZWx0YSBhIHJlc291cmNlIGRlbHRhCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBoYW5kbGVHbG9iYWxQcm9qZWN0Q2hhbmdlKGZpbmFsIElQcm9qZWN0IHByb2plY3QsIElSZXNvdXJjZURlbHRhIGRlbHRhKSB7CgkJaWYgKCFkZWx0YUNvbnRhaW5zQ2hhbmdlZE1vZHVsZXMoZGVsdGEpKQoJCQlyZXR1cm47CgkJCgkJLy8JIGNsZWFyIGNhY2hlCgkJTW9kdWxlRmFjdG9yeVtdIGZhY3RvcmllczIgPSBTZXJ2ZXJQbHVnaW4uZ2V0TW9kdWxlRmFjdG9yaWVzKCk7CgkJaW50IHNpemUgPSBmYWN0b3JpZXMyLmxlbmd0aDsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykKCQkJZmFjdG9yaWVzMltpXS5jbGVhck1vZHVsZUNhY2hlKCk7CgkJCgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiRmlyaW5nIGdsb2JhbCBwcm9qZWN0IGNoYW5nZSIpOwoJCS8vIGhhbmRsZSBwcm9qZWN0IGxldmVsIGNoYW5nZXMKCQlJdGVyYXRvciBpdGVyYXRvciA9IGZhY3Rvcmllcy5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSBmYWN0b3J5ID0gKFByb2plY3RNb2R1bGVGYWN0b3J5RGVsZWdhdGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiRmlyaW5nIHRvOiAiICsgZmFjdG9yeSk7CgkJCWZhY3RvcnkuaGFuZGxlUHJvamVjdENoYW5nZShwcm9qZWN0LCBkZWx0YSk7CgkJfQoJCQoJCS8vIGhhbmRsZSBpbnRlcm5hbCB1cGRhdGVzCgkJLy8gVE9ETyB1bmNvbW1lbnQgLSB0aGlzIGlzIGFscmVhZHkgYmVpbmcgY2FsbGVkIGJ5IHRoZSB0ZW1wb3JhcnkgdXBkYXRlUHJvamVjdHMoKSBtZXRob2QKCQkvKml0ZXJhdG9yID0gZmFjdG9yaWVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlQcm9qZWN0TW9kdWxlRmFjdG9yeURlbGVnYXRlIGZhY3RvcnkgPSAoUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSkgaXRlcmF0b3IubmV4dCgpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FUiwgIkZpcmluZyB0bzogIiArIGZhY3RvcnkpOwoJCQlmYWN0b3J5LmhhbmRsZVByb2plY3RJbnRlcm5hbENoYW5nZShwcm9qZWN0LCBkZWx0YSk7CgkJfSovCgkJCgkJZmlyZUdsb2JhbEV2ZW50cygpOwoJfQoKCS8qKgoJICogRmlyZSB0aGUgYWNjdW11bGF0ZWQgbW9kdWxlIGZhY3RvcnkgZXZlbnRzLgoJICovCglwcm90ZWN0ZWQgc3RhdGljIHZvaWQgZmlyZUdsb2JhbEV2ZW50cygpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJGaXJpbmcgZ2xvYmFsIG1vZHVsZSBldmVudCIpOwoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gZmFjdG9yaWVzLml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlQcm9qZWN0TW9kdWxlRmFjdG9yeURlbGVnYXRlIGZhY3RvcnkgPSAoUHJvamVjdE1vZHVsZUZhY3RvcnlEZWxlZ2F0ZSkgaXRlcmF0b3IubmV4dCgpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJGaXJpbmcgdG86ICIgKyBmYWN0b3J5KTsKCQkJZmFjdG9yeS51cGRhdGVQcm9qZWN0cygpOwoJCX0KCX0KCgkvKioKCSAqIFRlbXBvcmFyeSB0byBtYWtlIHN1cmUgdGhhdCBhbGwgcHJvamVjdCBtb2R1bGVzIGFyZSB1cGRhdGVkLgoJICovCglwcml2YXRlIHZvaWQgdXBkYXRlUHJvamVjdHMoKSB7CgkJSU1vZHVsZVtdIG1vZHVsZXMyID0gZ2V0TW9kdWxlcygpOwoJCWlmIChtb2R1bGVzMiAhPSBudWxsKSB7CgkJCWludCBzaXplID0gbW9kdWxlczIubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJaWYgKG1vZHVsZXMyW2ldIGluc3RhbmNlb2YgUHJvamVjdE1vZHVsZSkKCQkJCQkoKFByb2plY3RNb2R1bGUpIG1vZHVsZXMyW2ldKS51cGRhdGUoKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEhhbmRsZSBjaGFuZ2VzIHRvIGEgcHJvamVjdC4KCSAqIAoJICogQHBhcmFtIHByb2plY3QgYSBwcm9qZWN0CgkgKiBAcGFyYW0gZGVsdGEgYSByZXNvdXJjZSBkZWx0YQoJICovCglwcml2YXRlIHZvaWQgaGFuZGxlUHJvamVjdENoYW5nZShmaW5hbCBJUHJvamVjdCBwcm9qZWN0LCBJUmVzb3VyY2VEZWx0YSBkZWx0YSkgewoJCWlmKCFpbml0aWFsaXplZCkKCQkJY2FjaGVNb2R1bGVzKGZhbHNlKTsKCQlpZiAocHJvamVjdHMuY29udGFpbnNLZXkocHJvamVjdCkpIHsKCQkJLy8gYWxyZWFkeSBhIG1vZHVsZQoJCQlpZiAoKChkZWx0YS5nZXRLaW5kKCkgJiAgSVJlc291cmNlRGVsdGEuUkVNT1ZFRCkgIT0gMCkgfHwgIWlzVmFsaWRNb2R1bGUocHJvamVjdCkpIHsKCQkJCXJlbW92ZU1vZHVsZXMocHJvamVjdCk7CgkJCX0KCQl9IGVsc2UgewoJCQkvLyBub3QgYSBtb2R1bGUKCQkJaWYgKGlzVmFsaWRNb2R1bGUocHJvamVjdCkpIHsKCQkJCWFkZE1vZHVsZXMocHJvamVjdCk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBIYW5kbGUgY2hhbmdlcyB0byBhIHByb2plY3QuCgkgKiAKCSAqIEBwYXJhbSBwcm9qZWN0IGEgcHJvamVjdAoJICogQHBhcmFtIGRlbHRhIGEgcmVzb3VyY2UgZGVsdGEKCSAqLwoJLypwcml2YXRlIHZvaWQgaGFuZGxlUHJvamVjdEludGVybmFsQ2hhbmdlKGZpbmFsIElQcm9qZWN0IHByb2plY3QsIElSZXNvdXJjZURlbHRhIGRlbHRhKSB7CgkJZmluYWwgSVBhdGhbXSBwYXRocyA9IGdldExpc3RlbmVyUGF0aHMoKTsKCQlpZiAocGF0aHMgIT0gbnVsbCkgewoJCQlmaW5hbCBJTW9kdWxlW10gbW9kdWxlcyA9IGdldE1vZHVsZXMocHJvamVjdCk7CgkJCWlmIChtb2R1bGVzICE9IG51bGwpIHsKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbW9kdWxlcy5sZW5ndGg7IGkrKykgewoJCQkJCWZpbmFsIElNb2R1bGUgbW9kdWxlID0gbW9kdWxlc1tpXTsKCQkJCQlpZiAobW9kdWxlICE9IG51bGwgJiYgbW9kdWxlIGluc3RhbmNlb2YgUHJvamVjdE1vZHVsZSkgewoJCQkJCQkvLyBjaGVjayBmb3IgbGlzdGVuZXIgcGF0aHMKCQkJCQkJZmluYWwgaW50IHNpemUgPSBwYXRocy5sZW5ndGg7CgkJCQkJCWNsYXNzIFRlbXAgewoJCQkJCQkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJCQkJCQl9CgkJCQkJCWZpbmFsIFRlbXAgdGVtcCA9IG5ldyBUZW1wKCk7CgkJCQkJCXRyeSB7CgkJCQkJCQlkZWx0YS5hY2NlcHQobmV3IElSZXNvdXJjZURlbHRhVmlzaXRvcigpIHsKCQkJCQkJCQlwdWJsaWMgYm9vbGVhbiB2aXNpdChJUmVzb3VyY2VEZWx0YSB2aXNpdG9yRGVsdGEpIHsKCQkJCQkJCQkJaWYgKHRlbXAuZm91bmQpCgkJCQkJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJCQkJCUlQYXRoIHBhdGggPSB2aXNpdG9yRGVsdGEuZ2V0UHJvamVjdFJlbGF0aXZlUGF0aCgpOwoJCQkJCQkJCQkKCQkJCQkJCQkJYm9vbGVhbiBwcmVmaXggPSBmYWxzZTsKCQkJCQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplICYmICF0ZW1wLmZvdW5kOyBqKyspIHsKCQkJCQkJCQkJCWlmIChwYXRoc1tqXS5lcXVhbHMocGF0aCkpCgkJCQkJCQkJCQkJdGVtcC5mb3VuZCA9IHRydWU7CgkJCQkJCQkJCQllbHNlIGlmIChwYXRoLmlzUHJlZml4T2YocGF0aHNbal0pKQoJCQkJCQkJCQkJCXByZWZpeCA9IHRydWU7CgkJCQkJCQkJCX0KCQkJCQkJCQkJaWYgKHRlbXAuZm91bmQpIHsKCQkJCQkJCQkJCSgoUHJvamVjdE1vZHVsZSkgbW9kdWxlKS51cGRhdGUoKTsKCQkJCQkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQkJCQkJfSBlbHNlIGlmIChwcmVmaXgpCgkJCQkJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQkJCQkJZWxzZQoJCQkJCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCQkJCX0KCQkJCQkJCX0pOwoJCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3Igc2VhcmNoaW5nIGZvciBsaXN0ZW5pbmcgcGF0aHMiLCBlKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX0qLwoKCS8qKgoJICogQWRkIGEgbW9kdWxlIGZvciB0aGUgZ2l2ZW4gcHJvamVjdC4KCSAqIAoJICogQHBhcmFtIHByb2plY3QgYSBwcm9qZWN0CgkgKi8KCXByb3RlY3RlZCB2b2lkIGFkZE1vZHVsZXMoSVByb2plY3QgcHJvamVjdCkgewoJCUlNb2R1bGVbXSBtb2R1bGVzID0gbnVsbDsKCQl0cnkgewoJCQltb2R1bGVzID0gY3JlYXRlTW9kdWxlcyhwcm9qZWN0KTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBjcmVhdGluZyBtb2R1bGVzIiwgZSk7CgkJfQoJCWlmIChtb2R1bGVzID09IG51bGwgfHwgbW9kdWxlcy5sZW5ndGggPT0gMCkKCQkJcmV0dXJuOwoJCXByb2plY3RzLnB1dChwcm9qZWN0LCBtb2R1bGVzKTsKCQlhZGRlZCA9IG5ldyBBcnJheUxpc3QoMik7CgkJYWRkZWQuYWRkQWxsKEFycmF5cy5hc0xpc3QobW9kdWxlcykpOwoJfQoKCS8qKgoJICogUmVtb3ZlIHRoZSBtb2R1bGVzIHRoYXQgcmVwcmVzZW50cyB0aGUgZ2l2ZW4gcHJvamVjdC4KCSAqIAoJICogQHBhcmFtIHByb2plY3QgYSBwcm9qZWN0CgkgKi8KCXByb3RlY3RlZCB2b2lkIHJlbW92ZU1vZHVsZXMoSVByb2plY3QgcHJvamVjdCkgewoJCXRyeSB7CgkJCUlNb2R1bGVbXSBtb2R1bGVzID0gKElNb2R1bGVbXSkgcHJvamVjdHMuZ2V0KHByb2plY3QpOwoJCQkKCQkJcHJvamVjdHMucmVtb3ZlKHByb2plY3QpOwoJCQlpZiAocmVtb3ZlZCA9PSBudWxsKQoJCQkJcmVtb3ZlZCA9IG5ldyBBcnJheUxpc3QoMik7CgkJCWlmKG1vZHVsZXMgPT0gbnVsbCkKCQkJCXJldHVybjsKCQkJcmVtb3ZlZC5hZGRBbGwoQXJyYXlzLmFzTGlzdChtb2R1bGVzKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgcmVtb3ZpbmcgbW9kdWxlIHByb2plY3QiLCBlKTsKCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHByb2plY3QgbWF5IGNvbnRhaW4gbW9kdWxlcyBvZiB0aGUgY29ycmVjdCB0eXBlLgoJICogVGhpcyBtZXRob2QgaXMgdXNlZCBvbmx5IHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuCgkgKiAKCSAqIEBwYXJhbSBwcm9qZWN0IGEgcHJvamVjdAoJICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgcHJvamVjdCBtYXkgY29udGFpbiBtb2R1bGVzLCBhbmQKCSAqICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBpdCBkZWZpbml0ZWx5IGRvZXMgbm90CgkgKi8KCXByb3RlY3RlZCBhYnN0cmFjdCBib29sZWFuIGlzVmFsaWRNb2R1bGUoSVByb2plY3QgcHJvamVjdCk7CgoJLyoqCgkgKiBDcmVhdGVzIHRoZSBtb2R1bGVzIGZvciBhIGdpdmVuIHByb2plY3QuCgkgKiAKCSAqIEBwYXJhbSBwcm9qZWN0IGEgcHJvamVjdCB0byBjcmVhdGUgbW9kdWxlcyBmb3IKCSAqIEByZXR1cm4gYSBwb3NzaWJseSBlbXB0eSBhcnJheSBvZiBtb2R1bGVzCgkgKi8KCXByb3RlY3RlZCBhYnN0cmFjdCBJTW9kdWxlW10gY3JlYXRlTW9kdWxlcyhJUHJvamVjdCBwcm9qZWN0KTsKCQoJLyoqCgkgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIGF0IGxlYXN0IG9uZSBmaWxlIGluIHRoZSBkZWx0YSBpcyBjaGFuZ2VkLAoJICogYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCgkgKiAKCSAqIEBwYXJhbSBkZWx0YSBhIHJlc291cmNlIGRlbHRhCgkgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIGF0IGxlYXN0IG9uZSBmaWxlIGluIHRoZSBkZWx0YSBpcyBjaGFuZ2VkLAoJICogICAgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBkZWx0YUNvbnRhaW5zQ2hhbmdlZE1vZHVsZXMoSVJlc291cmNlRGVsdGEgZGVsdGEpIHsKCQljbGFzcyBUZW1wIHsKCQkJYm9vbGVhbiBiID0gZmFsc2U7CgkJfQoJCWZpbmFsIFRlbXAgdCA9IG5ldyBUZW1wKCk7CgkJdHJ5IHsKCQkJZGVsdGEuYWNjZXB0KG5ldyBJUmVzb3VyY2VEZWx0YVZpc2l0b3IoKSB7CgkJCQlwdWJsaWMgYm9vbGVhbiB2aXNpdChJUmVzb3VyY2VEZWx0YSBkZWx0YTIpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQkJCQlpZiAodC5iKQoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJLy9UcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsIGRlbHRhMi5nZXRSZXNvdXJjZSgpICsgIiAgIiArIGRlbHRhMi5nZXRLaW5kKCkgKyAiICIgKyBkZWx0YTIuZ2V0RmxhZ3MoKSk7CgkJCQkJaWYgKCIud3RwbW9kdWxlcyIuZXF1YWxzKGRlbHRhMi5nZXRSZXNvdXJjZSgpLmdldE5hbWUoKSkpIHsKCQkJCQkJdC5iID0gdHJ1ZTsKCQkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJCX0gZWxzZSBpZiAoIi5mYWNldHMiLmVxdWFscyhkZWx0YTIuZ2V0UmVzb3VyY2UoKS5nZXROYW1lKCkpKSB7CgkJCQkJCXQuYiA9IHRydWU7CgkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQl9IGVsc2UgaWYgKCIuY29tcG9uZW50Ii5lcXVhbHMoZGVsdGEyLmdldFJlc291cmNlKCkuZ2V0TmFtZSgpKSkgewoJCQkJCQl0LmIgPSB0cnVlOwoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQl9KTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkvLyBpZ25vcmUKCQl9CgkJLy9UcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJEZWx0YSBjb250YWlucyBjaGFuZ2U6ICIgKyB0LmIpOwoJCXJldHVybiB0LmI7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBsaXN0IG9mIHJlc291cmNlcyB0aGF0IHRoZSBtb2R1bGUgc2hvdWxkIGxpc3RlbiB0bwoJICogZm9yIHN0YXRlIGNoYW5nZXMuIFRoZSBwYXRocyBzaG91bGQgYmUgcHJvamVjdCByZWxhdGl2ZSBwYXRocy4KCSAqIFN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHByb3ZpZGUgdGhlIHBhdGhzLgoJICoKCSAqIEByZXR1cm4gYSBwb3NzaWJseSBlbXB0eSBhcnJheSBvZiBwYXRocwoJICovCglwcm90ZWN0ZWQgSVBhdGhbXSBnZXRMaXN0ZW5lclBhdGhzKCkgewoJCXJldHVybiBudWxsOwoJfQp9