LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5pbnRlcm5ldC5tb25pdG9yLmNvcmUuaW50ZXJuYWw7CgppbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUHJlZmVyZW5jZXM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuaW50ZXJuZXQubW9uaXRvci5jb3JlLio7Ci8qKgogKiAKICovCnB1YmxpYyBjbGFzcyBNb25pdG9yTWFuYWdlciB7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQUREID0gMDsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSEFOR0UgPSAxOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFTU9WRSA9IDI7CgoJLy8gbW9uaXRvcnMKCXByb3RlY3RlZCBMaXN0IG1vbml0b3JzOwoJcHJvdGVjdGVkIE1hcCB0aHJlYWRzID0gbmV3IEhhc2hNYXAoKTsKCQoJcHJvdGVjdGVkIExpc3QgbW9uaXRvckxpc3RlbmVycyA9IG5ldyBBcnJheUxpc3QoKTsKCQoJLy8gcmVxdWVzdHMKCXByb3RlY3RlZCBMaXN0IHJlcXVlc3RzID0gbmV3IEFycmF5TGlzdCgpOwoJCglwcm90ZWN0ZWQgTGlzdCByZXF1ZXN0TGlzdGVuZXJzID0gbmV3IEFycmF5TGlzdCgpOwoJCglwcml2YXRlIFByZWZlcmVuY2VzLklQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHBjbDsKCXByb3RlY3RlZCBib29sZWFuIGlnbm9yZVByZWZlcmVuY2VDaGFuZ2VzID0gZmFsc2U7CgkKCXByb3RlY3RlZCBzdGF0aWMgTW9uaXRvck1hbmFnZXIgaW5zdGFuY2U7CgkKCXB1YmxpYyBzdGF0aWMgTW9uaXRvck1hbmFnZXIgZ2V0SW5zdGFuY2UoKSB7CgkJaWYgKGluc3RhbmNlID09IG51bGwpCgkJCWluc3RhbmNlID0gbmV3IE1vbml0b3JNYW5hZ2VyKCk7CgkJcmV0dXJuIGluc3RhbmNlOwoJfQoJCglwcml2YXRlIE1vbml0b3JNYW5hZ2VyKCkgewoJCWxvYWRNb25pdG9ycygpOwoJCQoJCXBjbCA9IG5ldyBQcmVmZXJlbmNlcy5JUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgcHJvcGVydHlDaGFuZ2UoUHJlZmVyZW5jZXMuUHJvcGVydHlDaGFuZ2VFdmVudCBldmVudCkgewoJCQkJaWYgKGlnbm9yZVByZWZlcmVuY2VDaGFuZ2VzKQoJCQkJCXJldHVybjsKCQkJCVN0cmluZyBwcm9wZXJ0eSA9IGV2ZW50LmdldFByb3BlcnR5KCk7CgkJCQlpZiAocHJvcGVydHkuZXF1YWxzKCJtb25pdG9ycyIpKSB7CgkJCQkJbG9hZE1vbml0b3JzKCk7CgkJCQl9CgkJCX0KCQl9OwoJCQoJCU1vbml0b3JQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRQbHVnaW5QcmVmZXJlbmNlcygpLmFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIocGNsKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgZGlzcG9zZSgpIHsKCQlNb25pdG9yUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0UGx1Z2luUHJlZmVyZW5jZXMoKS5yZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKHBjbCk7Cgl9CgkKCXB1YmxpYyBJTW9uaXRvcldvcmtpbmdDb3B5IGNyZWF0ZU1vbml0b3IoKSB7CgkJcmV0dXJuIG5ldyBNb25pdG9yV29ya2luZ0NvcHkoKTsKCX0KCQoJcHVibGljIExpc3QgZ2V0TW9uaXRvcnMoKSB7CgkJcmV0dXJuIG5ldyBBcnJheUxpc3QobW9uaXRvcnMpOwoJfQoKCXByb3RlY3RlZCB2b2lkIGFkZE1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgewoJCWlmICghbW9uaXRvcnMuY29udGFpbnMobW9uaXRvcikpCgkJCW1vbml0b3JzLmFkZChtb25pdG9yKTsKCQlmaXJlTW9uaXRvckV2ZW50KG1vbml0b3IsIEFERCk7CgkJc2F2ZU1vbml0b3JzKCk7Cgl9CgkKCXByb3RlY3RlZCBib29sZWFuIGlzUnVubmluZyhJTW9uaXRvciBtb25pdG9yKSB7CgkJcmV0dXJuICh0aHJlYWRzLmdldChtb25pdG9yKSAhPSBudWxsKTsKCX0KCglwdWJsaWMgdm9pZCBzdGFydE1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJaWYgKCFtb25pdG9ycy5jb250YWlucyhtb25pdG9yKSkKCQkJcmV0dXJuOwoJCQoJCWlmIChBY2NlcHRUaHJlYWQuaXNQb3J0SW5Vc2UobW9uaXRvci5nZXRMb2NhbFBvcnQoKSkpCgkJCXRocm93IG5ldyBFeGNlcHRpb24oTW9uaXRvclBsdWdpbi5nZXRTdHJpbmcoIiVlcnJvclBvcnRJblVzZSIpKTsKCQkKCQlBY2NlcHRUaHJlYWQgdGhyZWFkID0gbmV3IEFjY2VwdFRocmVhZChtb25pdG9yKTsKCQl0aHJlYWQuc3RhcnRTZXJ2ZXIoKTsKCQl0aHJlYWRzLnB1dChtb25pdG9yLCB0aHJlYWQpOwoJfQoJCglwdWJsaWMgdm9pZCBzdG9wTW9uaXRvcihJTW9uaXRvciBtb25pdG9yKSB7CgkJaWYgKCFtb25pdG9ycy5jb250YWlucyhtb25pdG9yKSkKCQkJcmV0dXJuOwoJCQoJCUFjY2VwdFRocmVhZCB0aHJlYWQgPSAoQWNjZXB0VGhyZWFkKSB0aHJlYWRzLmdldChtb25pdG9yKTsKCQlpZiAodGhyZWFkICE9IG51bGwpIHsKCQkJdGhyZWFkLnN0b3BTZXJ2ZXIoKTsKCQkJdGhyZWFkcy5yZW1vdmUobW9uaXRvcik7CgkJfQoJfQoJCglwcm90ZWN0ZWQgdm9pZCByZW1vdmVNb25pdG9yKElNb25pdG9yIG1vbml0b3IpIHsKCQlpZiAobW9uaXRvci5pc1J1bm5pbmcoKSkKCQkJc3RvcE1vbml0b3IobW9uaXRvcik7CgkJbW9uaXRvcnMucmVtb3ZlKG1vbml0b3IpOwoJCWZpcmVNb25pdG9yRXZlbnQobW9uaXRvciwgUkVNT1ZFKTsKCQlzYXZlTW9uaXRvcnMoKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgbW9uaXRvckNoYW5nZWQoSU1vbml0b3IgbW9uaXRvcikgewoJCWZpcmVNb25pdG9yRXZlbnQobW9uaXRvciwgQ0hBTkdFKTsKCQlzYXZlTW9uaXRvcnMoKTsKCX0KCQoJLyoqCgkgKiBBZGQgbW9uaXRvciBsaXN0ZW5lci4KCSAqIAoJICogQHBhcmFtIGxpc3RlbmVyCgkgKi8KCXB1YmxpYyB2b2lkIGFkZE1vbml0b3JMaXN0ZW5lcihJTW9uaXRvckxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJbW9uaXRvckxpc3RlbmVycy5hZGQobGlzdGVuZXIpOwoJfQoKCS8qKgoJICogUmVtb3ZlIG1vbml0b3IgbGlzdGVuZXIuCgkgKiAKCSAqIEBwYXJhbSBsaXN0ZW5lcgoJICovCglwdWJsaWMgdm9pZCByZW1vdmVNb25pdG9yTGlzdGVuZXIoSU1vbml0b3JMaXN0ZW5lciBsaXN0ZW5lcikgewoJCW1vbml0b3JMaXN0ZW5lcnMucmVtb3ZlKGxpc3RlbmVyKTsKCX0KCQoJLyoqCgkgKiBGaXJlIGEgbW9uaXRvciBldmVudC4KCSAqIEBwYXJhbSBycgoJICogQHBhcmFtIHR5cGUKCSAqLwoJcHJvdGVjdGVkIHZvaWQgZmlyZU1vbml0b3JFdmVudChJTW9uaXRvciBtb25pdG9yLCBpbnQgdHlwZSkgewoJCU9iamVjdFtdIG9iaiA9IG1vbml0b3JMaXN0ZW5lcnMudG9BcnJheSgpOwoJCQoJCWludCBzaXplID0gb2JqLmxlbmd0aDsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlJTW9uaXRvckxpc3RlbmVyIGxpc3RlbmVyID0gKElNb25pdG9yTGlzdGVuZXIpIG9ialtpXTsKCQkJaWYgKHR5cGUgPT0gQUREKQoJCQkJbGlzdGVuZXIubW9uaXRvckFkZGVkKG1vbml0b3IpOwoJCQllbHNlIGlmICh0eXBlID09IENIQU5HRSkKCQkJCWxpc3RlbmVyLm1vbml0b3JDaGFuZ2VkKG1vbml0b3IpOwoJCQllbHNlIGlmICh0eXBlID09IFJFTU9WRSkKCQkJCWxpc3RlbmVyLm1vbml0b3JSZW1vdmVkKG1vbml0b3IpOwoJCX0KCX0KCQoJLyoqCgkgKiBSZXR1cm5zIGEgbGlzdCBvZiB0aGUgY3VycmVudCByZXF1ZXN0cy4KCSAqCgkgKiBAcmV0dXJuIGphdmEudXRpbC5MaXN0CgkgKi8KCXB1YmxpYyBMaXN0IGdldFJlcXVlc3RzKCkgewoJCXJldHVybiByZXF1ZXN0czsKCX0KCQoJLyoqCgkgKiBBZGQgYSBuZXcgcmVxdWVzdCByZXNwb25zZSBwYWlyLgoJICoKCSAqIEBwYXJhbSBwYWlyIG9yZy5lY2xpcHNlLnRjcGlwLm1vbml0b3IuUmVxdWVzdFJlc3BvbnNlCgkgKi8KCXB1YmxpYyB2b2lkIGFkZFJlcXVlc3QoSVJlcXVlc3QgcnIpIHsKCQlpZiAocmVxdWVzdHMuY29udGFpbnMocnIpKQoJCQlyZXR1cm47CgoJCXJlcXVlc3RzLmFkZChycik7CgkJZmlyZVJlcXVlc3RFdmVudChyciwgQUREKTsKCX0KCQoJcHVibGljIHZvaWQgcmVxdWVzdENoYW5nZWQoSVJlcXVlc3QgcnIpIHsKCQlmaXJlUmVxdWVzdEV2ZW50KHJyLCBDSEFOR0UpOwoJfQoJCglwdWJsaWMgdm9pZCByZW1vdmVSZXF1ZXN0KElSZXF1ZXN0IHJyKSB7CgkJaWYgKCFyZXF1ZXN0cy5jb250YWlucyhycikpCgkJCXJldHVybjsKCgkJcmVxdWVzdHMucmVtb3ZlKHJyKTsKCQlmaXJlUmVxdWVzdEV2ZW50KHJyLCBSRU1PVkUpOwoJfQoJCglwdWJsaWMgdm9pZCByZW1vdmVBbGxSZXF1ZXN0cygpIHsKCQlpbnQgc2l6ZSA9IHJlcXVlc3RzLnNpemUoKTsKCQlJUmVxdWVzdFtdIHJycyA9IG5ldyBJUmVxdWVzdFtzaXplXTsKCQlyZXF1ZXN0cy50b0FycmF5KHJycyk7CgkJCgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJcmVtb3ZlUmVxdWVzdChycnNbaV0pOwoJCX0KCX0KCQoJLyoqCgkgKiBBZGQgcmVxdWVzdCBsaXN0ZW5lci4KCSAqIAoJICogQHBhcmFtIGxpc3RlbmVyCgkgKi8KCXB1YmxpYyB2b2lkIGFkZFJlcXVlc3RMaXN0ZW5lcihJUmVxdWVzdExpc3RlbmVyIGxpc3RlbmVyKSB7CgkJcmVxdWVzdExpc3RlbmVycy5hZGQobGlzdGVuZXIpOwoJfQoKCS8qKgoJICogUmVtb3ZlIHJlcXVlc3QgbGlzdGVuZXIuCgkgKiAKCSAqIEBwYXJhbSBsaXN0ZW5lcgoJICovCglwdWJsaWMgdm9pZCByZW1vdmVSZXF1ZXN0TGlzdGVuZXIoSVJlcXVlc3RMaXN0ZW5lciBsaXN0ZW5lcikgewoJCXJlcXVlc3RMaXN0ZW5lcnMucmVtb3ZlKGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIEZpcmUgYSByZXF1ZXN0IGV2ZW50LgoJICogQHBhcmFtIHJyCgkgKiBAcGFyYW0gdHlwZQoJICovCglwcm90ZWN0ZWQgdm9pZCBmaXJlUmVxdWVzdEV2ZW50KElSZXF1ZXN0IHJyLCBpbnQgdHlwZSkgewoJCWludCBzaXplID0gcmVxdWVzdExpc3RlbmVycy5zaXplKCk7CgkJSVJlcXVlc3RMaXN0ZW5lcltdIHhybCA9IE1vbml0b3JQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRSZXF1ZXN0TGlzdGVuZXJzKCk7CgkJaW50IHNpemUyID0geHJsLmxlbmd0aDsKCQkKCQlJUmVxdWVzdExpc3RlbmVyW10gcmwgPSBuZXcgSVJlcXVlc3RMaXN0ZW5lcltzaXplICsgc2l6ZTJdOwoJCVN5c3RlbS5hcnJheWNvcHkoeHJsLCAwLCBybCwgMCwgc2l6ZTIpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQoJCQlybFtzaXplMiArIGldID0gKElSZXF1ZXN0TGlzdGVuZXIpIHJlcXVlc3RMaXN0ZW5lcnMuZ2V0KGkpOwoKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemUgKyBzaXplMjsgaSsrKSB7CgkJCUlSZXF1ZXN0TGlzdGVuZXIgbGlzdGVuZXIgPSBybFtpXTsKCQkJaWYgKHR5cGUgPT0gQUREKQoJCQkJbGlzdGVuZXIucmVxdWVzdEFkZGVkKHJyKTsKCQkJZWxzZSBpZiAodHlwZSA9PSBDSEFOR0UpCgkJCQlsaXN0ZW5lci5yZXF1ZXN0Q2hhbmdlZChycik7CgkJCWVsc2UgaWYgKHR5cGUgPT0gUkVNT1ZFKQoJCQkJbGlzdGVuZXIucmVxdWVzdFJlbW92ZWQocnIpOwoJCX0KCX0KCQoJcHJvdGVjdGVkIHZvaWQgbG9hZE1vbml0b3JzKCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIkxvYWRpbmcgbW9uaXRvcnMiKTsKCQkKCQltb25pdG9ycyA9IG5ldyBBcnJheUxpc3QoKTsKCQlQcmVmZXJlbmNlcyBwcmVmcyA9IE1vbml0b3JQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRQbHVnaW5QcmVmZXJlbmNlcygpOwoJCVN0cmluZyB4bWxTdHJpbmcgPSBwcmVmcy5nZXRTdHJpbmcoIm1vbml0b3JzIik7CgkJaWYgKHhtbFN0cmluZyAhPSBudWxsICYmIHhtbFN0cmluZy5sZW5ndGgoKSA+IDApIHsKCQkJdHJ5IHsKCQkJCUJ5dGVBcnJheUlucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHhtbFN0cmluZy5nZXRCeXRlcygpKTsKCQkJCUlNZW1lbnRvIG1lbWVudG8gPSBYTUxNZW1lbnRvLmxvYWRNZW1lbnRvKGluKTsKCQkKCQkJCUlNZW1lbnRvW10gY2hpbGRyZW4gPSBtZW1lbnRvLmdldENoaWxkcmVuKCJtb25pdG9yIik7CgkJCQlpZiAoY2hpbGRyZW4gIT0gbnVsbCkgewoJCQkJCWludCBzaXplID0gY2hpbGRyZW4ubGVuZ3RoOwoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQkJCU1vbml0b3IgbW9uaXRvciA9IG5ldyBNb25pdG9yKCk7CgkJCQkJCW1vbml0b3IubG9hZChjaGlsZHJlbltpXSk7CgkJCQkJCW1vbml0b3JzLmFkZChtb25pdG9yKTsKCQkJCQl9CgkJCQl9CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5XQVJOSU5HLCAiQ291bGQgbm90IGxvYWQgbW9uaXRvcnM6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CgkJCX0KCQl9Cgl9CgkKCXByb3RlY3RlZCB2b2lkIHNhdmVNb25pdG9ycygpIHsKCQl0cnkgewoJCQlpZ25vcmVQcmVmZXJlbmNlQ2hhbmdlcyA9IHRydWU7CgkJCVhNTE1lbWVudG8gbWVtZW50byA9IFhNTE1lbWVudG8uY3JlYXRlV3JpdGVSb290KCJtb25pdG9ycyIpOwoKCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb25pdG9ycy5pdGVyYXRvcigpOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQlNb25pdG9yIG1vbml0b3IgPSAoTW9uaXRvcikgaXRlcmF0b3IubmV4dCgpOwoJCQkJSU1lbWVudG8gY2hpbGQgPSBtZW1lbnRvLmNyZWF0ZUNoaWxkKCJtb25pdG9yIik7CgkJCQltb25pdG9yLnNhdmUoY2hpbGQpOwoJCQl9CgkJCQoJCQlTdHJpbmcgeG1sU3RyaW5nID0gbWVtZW50by5zYXZlVG9TdHJpbmcoKTsKCQkJUHJlZmVyZW5jZXMgcHJlZnMgPSBNb25pdG9yUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0UGx1Z2luUHJlZmVyZW5jZXMoKTsKCQkJcHJlZnMuc2V0VmFsdWUoIm1vbml0b3JzIiwgeG1sU3RyaW5nKTsKCQkJTW9uaXRvclBsdWdpbi5nZXRJbnN0YW5jZSgpLnNhdmVQbHVnaW5QcmVmZXJlbmNlcygpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBzYXZlIGJyb3dzZXJzIiwgZSk7CgkJfQoJCWlnbm9yZVByZWZlcmVuY2VDaGFuZ2VzID0gZmFsc2U7Cgl9Cn0=